bzoj 4320: ShangHai2006 Homework
把操作分类,,太神奇了。。。分为sqrt(300000),因为300000为最大的数据,所以这样的话就相当于分块,均摊复杂度应该是最优的。
小于的就直接暴力查询,大于的就按询问的模数分块查询,(一块一块的东西,23333并查集),然后因为是取模,所以这么做是对的。。
1 #include<bits/stdc++.h> 2 #define N 200005 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 using namespace std; 6 inline int ra() 7 { 8 int x=0,f=1; char ch=getchar(); 9 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 10 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 11 return x*f; 12 } 13 int ansy[N],ans[N],fa[N<<1],num[N]; 14 bool opt[N]; 15 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} 16 int main() 17 { 18 int n=ra(); char ch[2]; 19 int B=sqrt(300000),T=300000; 20 for (int i=1; i<=T; i++) fa[i]=i+1; 21 memset(ansy,0x7,sizeof(ansy)); 22 memset(ans,0x7,sizeof(ans)); 23 for (int i=1; i<=n; i++) 24 { 25 scanf("%s%d",ch,&num[i]); 26 if (ch[0]=='A') 27 { 28 opt[i]=1; 29 fa[num[i]]=num[i]; 30 for (int j=1; j<=B; j++) 31 ansy[j]=min(ansy[j],num[i]%j); 32 } 33 else if (num[i]<=B) ans[i]=ansy[num[i]]; 34 } 35 for (int i=n; i>=1; i--) 36 { 37 if (opt[i]) fa[num[i]]=num[i]+1; 38 else if (num[i]>B) 39 { 40 ans[i]=find(1)%num[i]; 41 for (int j=num[i]; j<=T; j+=num[i]) 42 { 43 int x=find(fa[j]); 44 if (x) ans[i]=min(ans[i],x%num[i]); 45 } 46 } 47 } 48 for (int i=1; i<=n; i++) 49 if (!opt[i]) printf("%d\n",ans[i]); 50 return 0; 51 }