VK Cup 2017 - Round 2
FallDream打的AB都FFT了,只剩一個我打的C,沒進前一百,之后看看馬拉松復活賽有沒機會唄。
?
A. Voltage Keepsake
題目大意:n個東西,每個東西一開始有bi能源,每秒消耗ai能源,每秒可以給一個東西加p能源,秒可以為實數,問至多多少秒內所有東西能源一直為正。(n<=100,000)
思路:二分答案,隨便check一下。不特判無解可能會炸精度。
#include<cstdio> #include<algorithm> using namespace std; #define lb long double inline int read() {int x;char c;while((c=getchar())<'0'||c>'9');for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=x*10+c-'0';return x; } #define MN 100000 int a[MN+5],b[MN+5]; int main() {int n=read(),p=read(),t,i;long long cnt=0;lb l,r,mid,sum;for(i=1;i<=n;++i)cnt+=a[i]=read(),b[i]=read();if(cnt<=p)return 0*puts("-1");for(t=100,l=0,r=1e12;--t;){mid=(l+r)/2;for(i=1,sum=0;i<=n;++i)sum+=max((lb)0,a[i]*mid-b[i]);(sum>p*mid?r:l)=mid;}printf("%.10lf",(double)l); }?
B. Volatile Kite
題目大意:給出一個n的點的凸多邊形,求一個最大的d,使得每個點任意移動d以內的距離,得到的新多邊形邊不相撞且仍是凸多邊形。(n<=1,000)
思路:枚舉相鄰三個點,d不會超過點i+1到點i與點i+2連線距離的一半,復雜度O(n)。
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; inline int read() {int x,f=1;char c;while((c=getchar())<'0'||c>'9')if(c=='-')f=0;for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=x*10+c-'0';return f?x:-x; } #define MN 1000 struct point{double x,y;}p[MN+5]; double dis(point a){return sqrt(a.x*a.x+a.y*a.y);} point operator-(point a,point b){return (point){a.x-b.x,a.y-b.y};} double operator*(point a,point b){return a.x*b.y-a.y*b.x;} int main() {int n=read(),i,j;double ans=1e18;for(i=0;i<n;++i)p[i].x=read(),p[i].y=read();p[n]=p[0];p[n+1]=p[1];for(i=0;i<n;++i)ans=min(ans,fabs((p[i+1]-p[i])*(p[i+2]-p[i]))/dis(p[i]-p[i+2]));printf("%.10lf",ans/2); }?
C. Vulnerable Kerbals
題目大意:給出m和n個0~m-1內的數,構造一個盡可能長的所有元素都在0~m-1內的數列,使所有前綴積模m不相同且不在n個數中出現過。(0<=n<m<=200,000)
思路:若前i個數的前綴積為x,前i+1個數的前綴積可以為y當且僅當ax-bm=y有解,即gcd(x,m)|y,若我們讓所有滿足這個條件的x,y,x向y連邊,題目即求最長鏈,gcd(x,m)相同的x在一個連通塊內,每個連通塊gcd(xi,m)向連通塊gcd(xj,m)(gcd(xi,m)|gcd(xj,m))連邊,得到一個邊數為O(nlogn)的拓撲圖,直接DP即可。
#include<cstdio> #include<vector> #include<algorithm> using namespace std; #define ll long long char B[1<<26],*S=B,C;int X; inline int read() {while((C=*S++)<'0'||C>'9');for(X=C-'0';(C=*S++)>='0'&&C<='9';)X=(X<<3)+(X<<1)+C-'0';return X; } #define MN 200000 int gcd(int x,int y){return y?gcd(y,x%y):x;} vector<int> v[MN+5]; int m,u[MN+5],f[MN+5],r[MN+5],ls=1; void exgcd(ll x,ll y,ll z,ll&a,ll&b) {if(!y){a=z/x;b=0;return;}ll aa,bb;exgcd(y,x%y,z,aa,bb);a=-bb;b=-aa-bb*(x/y); } void out(int x) {if(!x)return;out(r[x]);int i;ll a,b;for(i=0;i<v[x].size();++i)exgcd(ls,m,v[x][i],a,b),printf("%d ",(a%m+m)%m),ls=v[x][i]; } int main() {fread(B,1,1<<26,stdin);int n,i,j,mx=0;n=read();m=read();for(i=1;i<=n;++i)u[read()]=1;for(i=1;i<m;++i)if(!u[i])v[gcd(i,m)].push_back(i);for(i=1;i<m;++i){if((f[i]+=v[i].size())>f[mx])mx=i;for(j=i;j<m;j+=i)if(f[i]>f[j])f[j]=f[i],r[j]=i;}printf("%d\n",f[mx]+!u[0]);out(mx);if(!u[0])puts("0"); }?
D. Varying Kibibits
題目大意:給出n個數的集合T,F(S)的各位數字為集合S中各個數字對應位數字的最小值,例如F(123,321)=121,求的異或和。(n<=10^6,數字<=999,999)
思路:F值恰好為x的子集不好求,我們考慮求出F值各位數字都大等x的子集,也就是數字各位都大等于x的數的集合的所有子集,答案我們枚舉各位加一,容斥一下即可求出,現在問題是如何求出這個集合的子集和的平方和,只要同時維護一個集合的子集和的和、子集和的平方和、集合大小,就可以支持合并集合和刪除集合(稍微推一下式子,挺簡單的,或者看下面的代碼),數字各位都大等于x的集合同樣也可以容斥求出,總復雜度O(2^6*n),可能需要卡卡常數,正解貌似是O(6n)的,以后補。
#include<cstdio> char B[1<<26],*S=B,C;int X; inline int read() {while((C=*S++)<'0'||C>'9');for(X=C-'0';(C=*S++)>='0'&&C<='9';)X=X*10+C-'0';return X; } #define MN 1000000 #define MOD 1000000007 int a[MN+5],p2[MN+5],r2[MN+5],pw[7]; struct data {int s1,s2,sz;data(int s1=0,int s2=0,int sz=0):s1(s1),s2(s2),sz(sz){}void operator+=(const data&b){s2=(1LL*s2*p2[b.sz]+1LL*b.s2*p2[sz]+2LL*s1*b.s1)%MOD;s1=(1LL*s1*p2[b.sz]+1LL*b.s1*p2[sz])%MOD;sz+=b.sz;}void operator-=(const data&b){sz-=b.sz;s1=((s1-1LL*b.s1*p2[sz])%MOD+MOD)*r2[b.sz]%MOD;s2=((s2-2LL*s1*b.s1-1LL*b.s2*p2[sz])%MOD+MOD)*r2[b.sz]%MOD;} }s[MN+5]; void solve1(int x,int k,int d,int p) {if(d>5){if(x!=k)if(p>0)s[x]+=s[k];else s[x]-=s[k];return;}solve1(x,k,d+1,p);if(k%pw[d+1]/pw[d]<9)solve1(x,k+pw[d],d+1,-p); } inline int mod(int x){if(x>=MOD)x-=MOD;if(x<0)x+=MOD;return x;} void solve2(int x,int k,int d,int p) {if(d>5){if(x!=k)s[x].s2=mod(s[x].s2+p*s[k].s2);return;}solve2(x,k,d+1,p);if(k%pw[d+1]/pw[d]<9)solve2(x,k+pw[d],d+1,-p); } int main() {B[fread(B,1,1<<26,stdin)]=0;int n=read(),i;long long ans=0;while(n--)++a[read()];for(p2[0]=i=1;i<=MN;++i)p2[i]=(p2[i-1]<<1)%MOD;for(r2[0]=i=1;i<=MN;++i)r2[i]=(r2[i-1]*((MOD+1LL)>>1))%MOD;for(pw[0]=i=1;i<7;++i)pw[i]=pw[i-1]*10;for(i=MN;i--;){solve1(i,i,0,-1);while(a[i]--)s[i]+=data(i,1LL*i*i%MOD,1);}for(i=1;i<MN;++i)solve2(i,i,0,1),ans^=1LL*i*s[i].s2;printf("%I64d",ans); }?
轉載于:https://www.cnblogs.com/ditoly/p/VK-Cup-2017-R2.html
總結
以上是生活随笔為你收集整理的VK Cup 2017 - Round 2的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java当中的IO一
- 下一篇: [BZOJ1097][POI2007]旅