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 }

 

posted @ 2017-03-01 08:32  ws_ccd  阅读(166)  评论(0编辑  收藏  举报