BYRBT

POI 2010

Guilds:

孤立点无解,剩下的乱染色就行了。

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<cctype>
  5 
  6 using namespace std;
  7 
  8 const int BUF_SIZE = 30;
  9 char buf[BUF_SIZE], *buf_s = buf, *buf_t = buf + 1;
 10   
 11 #define PTR_NEXT() \
 12     { \
 13         buf_s ++; \
 14         if (buf_s == buf_t) \
 15         { \
 16             buf_s = buf; \
 17             buf_t = buf + fread(buf, 1, BUF_SIZE, stdin); \
 18         } \
 19     }
 20    
 21 #define readint(_n_) \
 22     { \
 23         while (*buf_s != '-' && !isdigit(*buf_s)) \
 24             PTR_NEXT(); \
 25         bool register _nega_ = false; \
 26         if (*buf_s == '-') \
 27         { \
 28             _nega_ = true; \
 29             PTR_NEXT(); \
 30         } \
 31         int register _x_ = 0; \
 32         while (isdigit(*buf_s)) \
 33         { \
 34             _x_ = _x_ * 10 + *buf_s - '0'; \
 35             PTR_NEXT(); \
 36         } \
 37         if (_nega_) \
 38             _x_ = -_x_; \
 39         (_n_) = (_x_); \
 40     }
 41 
 42 const int maxn=200010;
 43 const int maxm=500010;
 44 
 45 int n,m,en,res[maxn],q[maxn];
 46 
 47 bool use[maxn];
 48 
 49 struct edge
 50 {
 51     int e;
 52     edge *next;
 53 }*v[maxn],ed[maxm<<1];
 54 
 55 void add_edge(int s,int e)
 56 {
 57     en++;
 58     ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;
 59 }
 60 
 61 int main()
 62 {
 63     freopen("guilds.in","r",stdin);
 64     freopen("guilds.out","w",stdout);
 65 
 66     readint(n);
 67     readint(m);
 68     int s,e;
 69     for (int a=1;a<=m;a++)
 70     {
 71         readint(s);
 72         readint(e);
 73         add_edge(s,e);
 74         add_edge(e,s);
 75         use[s]=use[e]=true;
 76     }
 77     for (int a=1;a<=n;a++)
 78         if (!use[a])
 79         {
 80             printf("NIE\n");
 81             return 0;
 82         }
 83     printf("TAK\n");
 84     for (int a=1;a<=n;a++)
 85         if (!res[a])
 86         {
 87             res[a]=1;
 88             int front=1,tail=1;
 89             q[1]=a;
 90             for (;front<=tail;)
 91             {
 92                 int now=q[front++];
 93                 for (edge *e=v[now];e;e=e->next)
 94                     if (!res[e->e])
 95                     {
 96                         res[e->e]=3-res[now];
 97                         q[++tail]=e->e;
 98                     }
 99             }
100         }
101     for (int a=1;a<=n;a++)
102         if (res[a]==1) printf("K\n");
103         else printf("S\n");
104 
105     return 0;
106 }
View Code

 

Beads:

直接枚举长度检验即可。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<set>
 5 #include<vector>
 6 
 7 using namespace std;
 8 
 9 #define ull unsigned long long
10 
11 const int maxn=200010;
12 const ull base=999997;
13 
14 int n,z[maxn];
15 
16 ull h1[maxn],h2[maxn],bit[maxn];
17 
18 vector<int> res;
19 
20 ull calc1(int l,int r)
21 {
22     return h1[r]-h1[l-1]*bit[r-l+1];
23 }
24 
25 ull calc2(int l,int r)
26 {
27     return h2[l]-h2[r+1]*bit[r-l+1];
28 }
29 
30 int calc(int l)
31 {
32     set<ull> se;
33     for (int a=1;a+l-1<=n;a+=l)
34         se.insert(min(calc1(a,a+l-1),calc2(a,a+l-1)));
35     return (int)se.size();
36 }
37 
38 int main()
39 {
40     freopen("beads.in","r",stdin);
41     freopen("beads.out","w",stdout);
42 
43     scanf("%d",&n);
44     for (int a=1;a<=n;a++)
45         scanf("%d",&z[a]);
46     bit[0]=1;
47     for (int a=1;a<=n;a++)
48         bit[a]=bit[a-1]*base;
49     for (int a=1;a<=n;a++)
50         h1[a]=h1[a-1]*base+z[a];
51     for (int a=n;a>=1;a--)
52         h2[a]=h2[a+1]*base+z[a];
53     int ans=0;
54     for (int a=1;a<=n;a++)
55     {
56         int v=calc(a);
57         if (v>ans)
58         {
59             ans=v;
60             res.clear();
61         }
62         if (v==ans) res.push_back(a);
63     }
64     printf("%d %d\n",ans,(int)res.size());
65     for (int a=0;a<(int)res.size();a++)
66     {
67         printf("%d",res[a]);
68         if (a==(int)res.size()-1) printf("\n");
69         else printf(" ");
70     }
71 
72     return 0;
73 }
View Code



Divine Divisors:

首先预处理出所有1-10^6之类的质数并且把所有的数的该部分因子去除,那么剩下的所有数的可能性就只有:p、p^2、pq这三种可能性。第一种可以直接使用miller rabin判断即可(要用快速加法)。第二种也可以直接处理。第三种可以先处理出所有最大公约数再直接算贡献即可。

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<cmath>
  5 
  6 using namespace std;
  7 
  8 #ifdef unix
  9 #define LL "%lld"
 10 #else
 11 #define LL "%I64d"
 12 #endif
 13 
 14 const int maxn=610;
 15 const int maxp=1000010;
 16 const int prime_check[]={0,2,3,11,67};
 17 
 18 int n,cnt,p[maxp],num[maxp],y[maxn];
 19 
 20 long long z[maxn];
 21 
 22 bool use[maxp];
 23 
 24 long long gcd(long long a,long long b)
 25 {
 26     if (!b) return a;
 27     else return gcd(b,a%b);
 28 }
 29 
 30 long long add(long long a,long long b,long long c)
 31 {
 32     long long ans=0;
 33     while (b)
 34     {
 35         if (b&1)
 36         {
 37             ans+=a;
 38             if (ans>=c) ans-=c;
 39         }
 40         a+=a;
 41         if (a>=c) a-=c;
 42         b>>=1;
 43     }
 44     return ans;
 45 }
 46 
 47 long long mul(long long a,long long b,long long c)
 48 {
 49     long long ans=1;
 50     while (b)
 51     {
 52         if (b&1) ans=add(ans,a,c);
 53         a=add(a,a,c);
 54         b>>=1;
 55     }
 56     return ans;
 57 }
 58 
 59 bool prime(long long n)
 60 {
 61     if (n<2) return false;
 62     if (n==2) return true;
 63     if (!(n&1)) return false;
 64     long long d=n,r=0;
 65     d--;
 66     while (!(d&1))
 67     {
 68         r++;
 69         d>>=1;
 70     }
 71     for (int a=1;a<=4;a++)
 72     {
 73         long long now=prime_check[a];
 74         if (now==n) continue;
 75         long long v=mul(now,d,n);
 76         if (v==1 || v==n-1) continue;
 77         bool find=false;
 78         for (int b=1;b<r && !find;b++)
 79         {
 80             v=add(v,v,n);
 81             if (v==n-1) find=true;
 82         }
 83         if (!find) return false;
 84     }
 85     return true;
 86 }
 87 
 88 bool call_prime(long long v)
 89 {
 90     if (v<2) return false;
 91     for (long long a=2;a*a<=v;a++)
 92         if (v%a==0) return false;
 93     return true;
 94 }
 95 
 96 int main()
 97 {
 98     freopen("divine.in","r",stdin);
 99     freopen("divine.out","w",stdout);
100 
101     for (int a=2;a<=1000000;a++)
102     {
103         if (!use[a])
104         {
105             cnt++;
106             p[cnt]=a;
107         }
108         for (int b=1;p[b]*a<=1000000;b++)
109         {
110             use[p[b]*a]=true;
111             if (a%p[b]==0) break;
112         }
113     }
114     scanf("%d",&n);
115     for (int a=1;a<=n;a++)
116         scanf(LL,&z[a]);
117     for (int a=1;a<=n;a++)
118         for (int b=1;b<=cnt;b++)
119             while (z[a]%p[b]==0)
120                 z[a]/=p[b],num[b]++;
121     for (int a=1;a<=n;a++)
122         for (int b=a+1;b<=n;b++)
123             if (z[a]!=1 && z[b]!=1 && z[a]!=z[b])
124             {
125                 long long g=gcd(z[a],z[b]);
126                 if (g!=1)
127                 {
128                     cnt++;
129                     for (int c=1;c<=n;c++)
130                         while (z[c]%g==0)
131                             z[c]/=g,num[cnt]++;
132                     if (z[a]!=1)
133                     {
134                         g=z[a];
135                         cnt++;
136                         for (int c=1;c<=n;c++)
137                             while (z[c]%g==0)
138                                 z[c]/=g,num[cnt]++;
139                     }
140                     if (z[b]!=1)
141                     {
142                         g=z[b];
143                         cnt++;
144                         for (int c=1;c<=n;c++)
145                             while (z[c]%g==0)
146                                 z[c]/=g,num[cnt]++;
147                     }
148                 }
149             }
150     for (int a=1;a<=n;a++)
151         if (z[a]!=1)
152         {
153             long long v=(long long)(sqrt(z[a]));
154             if (v*v==z[a])
155             {
156                 cnt++;
157                 for (int b=1;b<=n;b++)
158                     while (z[b]%v==0)
159                         z[b]/=v,num[cnt]++;
160             }
161         }
162     for (int a=1;a<=n;a++)
163         if (prime(z[a]))
164         {
165             cnt++;
166             long long v=z[a];
167             for (int b=1;b<=n;b++)
168                 while (z[b]%v==0)
169                     z[b]/=v,num[cnt]++;
170         }
171     int ans=0,res=0;
172     for (int a=1;a<=cnt;a++)
173     {
174         if (num[a]>ans)
175         {
176             ans=num[a];
177             res=0;
178         }
179         if (num[a]==ans) res++;
180     }
181     for (int a=1;a<=n;a++)
182         if (z[a]!=1)
183         {
184             int nownum=0;
185             for (int b=a;b<=n;b++)
186                 if (z[b]==z[a]) nownum++;
187             if (nownum>ans)
188             {
189                 ans=nownum;
190                 res=0;
191             }
192             if (nownum==ans) res+=2;
193         }
194     printf("%d\n",ans);
195     ans=res;
196     y[1]=1;
197     int l=1;
198     while (ans)
199     {
200         for (int a=1;a<=l;a++)
201             y[a]<<=1;
202         for (int a=1;a<=l;a++)
203             if (y[a]>=10)
204             {
205                 y[a]-=10;
206                 y[a+1]++;
207             }
208         if (y[l+1]) l++;
209         ans--;
210     }
211     y[1]--;
212     for (int a=l;a>=1;a--)
213         printf("%d",y[a]);
214     printf("\n");
215 
216     return 0;
217 }
View Code



Intelligence Test:

每次暴力二分找下一个位置。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<vector>
 6 
 7 using namespace std;
 8 
 9 const int maxn=1000010;
10 
11 int n,m;
12 
13 vector<int> z[maxn];
14 
15 int main()
16 {
17     freopen("test.in","r",stdin);
18     freopen("test.out","w",stdout);
19 
20     scanf("%d",&n);
21     for (int a=1;a<=n;a++)
22     {
23         int v;
24         scanf("%d",&v);
25         z[v].push_back(a);
26     }
27     scanf("%d",&m);
28     for (int a=1;a<=m;a++)
29     {
30         scanf("%d",&n);
31         int p=0;
32         bool able=true;
33         for (int b=1;b<=n;b++)
34         {
35             int v;
36             scanf("%d",&v);
37             int x=upper_bound(z[v].begin(),z[v].end(),p)-z[v].begin();
38             if (x==(int)z[v].size() || z[v][x]<=p)
39             {
40                 able=false;
41                 for (int c=b+1;c<=n;c++)
42                     scanf("%d",&v);
43                 break;
44             }
45             p=z[v][x];
46         }
47         if (able) printf("TAK\n");
48         else printf("NIE\n");
49     }
50 
51     return 0;
52 }
View Code

 

Antisymmetry:

只对中间位置做manachar。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 
 8 const int maxn=1000010;
 9 
10 int n,f[maxn],z[maxn];
11 
12 char s[maxn];
13 
14 int main()
15 {
16     freopen("antisymmetry.in","r",stdin);
17     freopen("antisymmetry.out","w",stdout);
18 
19     scanf("%d",&n);
20     scanf("%s",s+1);
21     for (int a=n;a>=1;a--)
22         z[a*2]=(s[a]=='0' ? 0 : 2);
23     n<<=1;
24     n++;
25     for (int a=1;a<=n;a+=2)
26         z[a]=1;
27     f[1]=1;
28     int nowr=1,nowm=1;
29     for (int a=1;a<=n;a+=2)
30     {
31         if (a<=nowr) f[a]=min(nowr-a+1,f[nowm+nowm-a]);
32         else f[a]=1;
33         while (a+f[a]<n && a-f[a]>0 && z[a+f[a]]+z[a-f[a]]==2)
34             f[a]++;
35         if (a+f[a]-1>=nowr)
36         {
37             nowr=a+f[a]-1;
38             nowm=a;
39         }
40     }
41     long long ans=0;
42     for (int a=1;a<=n;a+=2)
43         ans+=f[a]>>1;
44     printf("%lld\n",ans);
45 
46     return 0;
47 }
View Code

 

Hamsters:

矩阵倍增。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<vector>
 5 
 6 using namespace std;
 7 
 8 #define ull unsigned long long
 9 #define calc(a,b,c) (h[a][c]-h[a][b-1]*bit[c-b+1])
10 
11 const int maxn=210;
12 const int maxl=100010;
13 const ull base=10007;
14 
15 int n,m,l[maxn];
16 
17 long long m1[maxn],m2[maxn][maxn],m3[maxn],m4[maxn][maxn];
18 
19 ull bit[maxl];
20 
21 char s[maxl];
22 
23 vector<ull> h[maxn];
24 
25 int main()
26 {
27     freopen("hamsters.in","r",stdin);
28     freopen("hamsters.out","w",stdout);
29 
30     scanf("%d%d",&n,&m);
31     for (int a=1;a<=n;a++)
32     {
33         scanf("%s",s+1);
34         l[a]=strlen(s+1);
35         ull nowv=0;
36         h[a].push_back(nowv);
37         for (int b=1;b<=l[a];b++)
38         {
39             nowv=nowv*base+s[b];
40             h[a].push_back(nowv);
41         }
42     }
43     bit[0]=1;
44     for (int a=1;a<=100000;a++)
45         bit[a]=bit[a-1]*base;
46     for (int a=1;a<=n;a++)
47         for (int b=1;b<=n;b++)
48         {
49             int vx=l[b];
50             for (int c=(l[a]>l[b] ? l[a]-l[b]+2 : 2);c<=l[a];c++)
51                 if (calc(a,c,l[a])==calc(b,1,l[a]-c+1))
52                 {
53                     vx=l[b]-(l[a]-c+1);
54                     break;
55                 }
56             m2[a][b]=vx;
57         }
58     for (int a=1;a<=n;a++)
59         m1[a]=l[a];
60     m--;
61     while (m)
62     {
63         if (m&1)
64         {
65             memset(m3,0x3f,sizeof(m3));
66             for (int a=1;a<=n;a++)
67                 for (int b=1;b<=n;b++)
68                     m3[b]=min(m3[b],m1[a]+m2[a][b]);
69             for (int a=1;a<=n;a++)
70                 m1[a]=m3[a];
71         }
72         memset(m4,0x3f,sizeof(m4));
73         for (int a=1;a<=n;a++)
74             for (int b=1;b<=n;b++)
75                 for (int c=1;c<=n;c++)
76                     m4[a][c]=min(m4[a][c],m2[a][b]+m2[b][c]);
77         for (int a=1;a<=n;a++)
78             for (int b=1;b<=n;b++)
79                 m2[a][b]=m4[a][b];
80         m>>=1;
81     }
82     for (int a=1;a<=n;a++)
83         m1[1]=min(m1[1],m1[a]);
84     printf("%lld\n",m1[1]);
85 
86     return 0;
87 }
View Code



Blocks:

首先将所有数都减去K,那么问题就转化成了最长的一段和大于等于0的长度。考虑起点,如果左边有一个比它值小的点就肯定不优,终点亦然。所以用单调队列维护这个序列,然后发现对于起点终点的位置是单调递增的,所以再扫一遍出答案。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 
 8 const int maxn=1000010;
 9 
10 int n,m,y[maxn],p1[maxn],p2[maxn];
11 
12 long long z[maxn],s1[maxn],s2[maxn];
13 
14 int main()
15 {
16     freopen("blocks.in","r",stdin);
17     freopen("blocks.out","w",stdout);
18 
19     scanf("%d%d",&n,&m);
20     for (int a=1;a<=n;a++)
21         scanf("%d",&y[a]);
22     for (int a=1;a<=m;a++)
23     {
24         int k;
25         scanf("%d",&k);
26         for (int b=1;b<=n;b++)
27             z[b]=z[b-1]+y[b]-k;
28         int size1=1;
29         s1[1]=0;p1[1]=0;
30         for (int b=1;b<=n;b++)
31         {
32             while (size1 && s1[size1]<z[b])
33                 size1--;
34             s1[++size1]=z[b];
35             p1[size1]=b;
36         }
37         int size2=1;
38         s2[1]=z[n];p2[1]=n+1;
39         for (int b=n;b>=0;b--)
40         {
41             while (size2 && s2[size2]>z[b])
42                 size2--;
43             s2[++size2]=z[b];
44             p2[size2]=b;
45         }
46         reverse(s2+1,s2+size2+1);
47         reverse(p2+1,p2+size2+1);
48         int ans=0;
49         for (int b=1,c=1;b<=size2;b++)
50         {
51             while (c<=size1 && s1[c]>=s2[b])
52                 c++;
53             c--;
54             ans=max(ans,p1[c]-p2[b]);
55         }
56         printf("%d",ans);
57         if (a==m) printf("\n");
58         else printf(" ");
59     }
60 
61     return 0;
62 }
View Code



Sheep:

一条对角线如果在一开始可行那么它将是一直可行的,所以我们预处理出所有合法的对角线。处理的方法是枚举一个起点然后用极角排序判断即可。最后再用一次DP做出答案即可。

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<algorithm>
  6 
  7 using namespace std;
  8 
  9 const int maxn=610;
 10 const int maxm=20010;
 11 const double pi=acos(-1.0);
 12 const double eps=1e-10;
 13 
 14 int n,m,mo,f[maxn][maxn];
 15 
 16 bool g[maxn][maxn],con[maxn][maxn];
 17 
 18 struct rec
 19 {
 20     double arc;
 21     int opt;
 22     bool operator<(const rec &a)const
 23     {
 24         return arc<a.arc;
 25     }
 26 }x[maxn+maxm];
 27 
 28 struct point
 29 {
 30     int x,y;
 31     void init()
 32     {
 33         scanf("%d%d",&x,&y);
 34     }
 35 }z[maxn],y[maxm];
 36 
 37 int cross(point a,point b,point c)
 38 {
 39     return (a.x-b.x)*(a.y-c.y)-(a.y-b.y)*(a.x-c.x);
 40 }
 41 
 42 int sgn(double v)
 43 {
 44     if (fabs(v)<=eps) return 0;
 45     if (v>0) return 1;
 46     else return -1;
 47 }
 48 
 49 bool check(int a,int b)
 50 {
 51     int cnt1=0,cnt2=0;
 52     for (int c=1;c<=m;c++)
 53     {
 54         int v=cross(z[a],z[b],y[c]);
 55         if (v==0) return false;
 56         if (v>0) cnt1++;
 57         else cnt2++;
 58     }
 59     return cnt1%2==0 && cnt2%2==0;
 60 }
 61 
 62 int solve(int l,int r)
 63 {
 64     if (g[l][r]) return f[l][r];
 65     g[l][r]=true;
 66     int &ans=f[l][r];
 67     ans=0;
 68     if (l+1>=r) return ans=1;
 69     if (l+2==r) return ans=con[l][r];
 70     for (int a=l+1;a<r;a++)
 71         if (con[l][a] && con[r][a])
 72         {
 73             ans+=(long long)solve(l,a)*solve(a,r)%mo;
 74             ans%=mo;
 75         }
 76     return ans;
 77 }
 78 
 79 int main()
 80 {
 81     freopen("sheep.in","r",stdin);
 82     freopen("sheep.out","w",stdout);
 83 
 84     scanf("%d%d%d",&n,&m,&mo);
 85     for (int a=1;a<=n;a++)
 86         z[a].init();
 87     for (int a=1;a<=m;a++)
 88         y[a].init();
 89     z[n+1]=z[1];
 90     z[0]=z[n];
 91     for (int a=1;a<=n;a++)
 92     {
 93         double v=max(atan2(z[a+1].y-z[a].y,z[a+1].x-z[a].x),atan2(z[a-1].y-z[a].y,z[a-1].x-z[a].x));
 94         int cnt=0;
 95         for (int b=1;b<=n;b++)
 96             if (b!=a)
 97             {
 98                 cnt++;
 99                 x[cnt].opt=b;
100                 x[cnt].arc=atan2(z[b].y-z[a].y,z[b].x-z[a].x);
101                 if (sgn(x[cnt].arc-v)>0) x[cnt].arc-=2*pi;
102             }
103         for (int b=1;b<=m;b++)
104         {
105             cnt++;
106             x[cnt].opt=0;
107             x[cnt].arc=atan2(y[b].y-z[a].y,y[b].x-z[a].x);
108             if (sgn(x[cnt].arc-v)>0) x[cnt].arc-=2*pi;
109         }
110         sort(x+1,x+cnt+1);
111         int cx=0;
112         x[0].arc=-100;x[cnt+1].arc=100;
113         for (int b=1;b<=cnt;b++)
114             if (x[b].opt)
115             {
116                 if (sgn(x[b].arc-x[b-1].arc)==0 || sgn(x[b].arc-x[b+1].arc)==0) ;
117                 else
118                 {
119                     if (cx%2==0) con[a][x[b].opt]=true;
120                 }
121             }
122             else cx++;
123     }
124     int ans=0;
125     for (int a=2;a<=n;a++)
126         if (con[n][a] && con[1][a])
127         {
128             ans+=(long long)solve(1,a)*solve(a,n)%mo;
129             ans%=mo;
130         }
131     printf("%d\n",ans);
132 
133     return 0;
134 }
View Code



The Minima Game:

DP,扫一遍出解。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 
 8 const int maxn=1000010;
 9 
10 int n,z[maxn];
11 
12 int main()
13 {
14     freopen("minima.in","r",stdin);
15     freopen("minima.out","w",stdout);
16 
17     scanf("%d",&n);
18     for (int a=1;a<=n;a++)
19         scanf("%d",&z[a]);
20     sort(z+1,z+n+1);
21     int ans=z[1];
22     for (int a=2;a<=n;a++)
23         ans=max(ans,z[a]-ans);
24     printf("%d\n",ans);
25 
26     return 0;
27 }
View Code

 

Frog:

扫一遍后倍增。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 
 7 #define dis(a,b) z[a]-z[b]
 8 
 9 const int maxn=1000010;
10 const long long INF=0x3f3f3f3f3f3f3f3fll;
11 
12 int n,k,to[maxn][2],res[maxn];
13 
14 long long m,z[maxn];
15 
16 int main()
17 {
18     freopen("frog.in","r",stdin);
19     freopen("frog.out","w",stdout);
20 
21     scanf("%d%d%lld",&n,&k,&m);
22     for (int a=1;a<=n;a++)
23         scanf("%lld",&z[a]);
24     int front1=1,tail1=-1;
25     int front2=1,tail2=1;
26     for (int a=1;a<=n;a++)
27     {
28         tail1++;
29         front2++;
30         int size=tail1-front1+1+tail2-front2+1;
31         while (true)
32         {
33             if (size<k) 
34             {
35                 long long disl,disr;
36                 if (front1>1) disl=dis(a,front1-1);
37                 else disl=INF;
38                 if (tail2<n) disr=dis(tail2+1,a);
39                 else disr=INF;
40                 if (disl<=disr) front1--;
41                 else tail2++;
42                 size++;
43             }    
44             else
45             {
46                 long long disl,disr;
47                 if (front1>1) disl=dis(a,front1-1);
48                 else disl=INF;
49                 if (tail2<n) disr=dis(tail2+1,a);
50                 else disr=INF;
51                 if (disl<=dis(tail2,a) && front2<=tail2) front1--,tail2--;
52                 else
53                 {
54                     if (disr<dis(a,front1) && front1<=tail1) front1++,tail2++;
55                     else break;
56                 }
57             }
58         }
59         if (front1<=tail1 && dis(a,front1)>=dis(tail2,a)) to[a][0]=front1;
60         else to[a][0]=tail2;
61     }
62     for (int a=1;a<=n;a++)
63         res[a]=a;
64     while (m)
65     {
66         if (m&1)
67         {
68             for (int a=1;a<=n;a++)
69                 res[a]=to[res[a]][0];
70         }
71         m>>=1;
72         for (int a=1;a<=n;a++)
73             to[a][1]=to[to[a][0]][0];
74         for (int a=1;a<=n;a++)
75             to[a][0]=to[a][1];
76     }
77     for (int a=1;a<=n;a++)
78     {
79         printf("%d",res[a]);
80         if (a==n) printf("\n");
81         else printf(" ");
82     }
83 
84     return 0;
85 }
View Code

 

Bridges:

二分答案后混合图欧拉回路。

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<algorithm>
  5 
  6 using namespace std;
  7 
  8 const int maxn=1010;
  9 const int maxm=2010;
 10 const int INF=0x3f3f3f3f;
 11 
 12 int n,m,en,size,in[maxn],out[maxn],s[maxm],t[maxm],v1[maxm],v2[maxm],depth[maxn],q[maxn],res[maxm];
 13 
 14 struct edge
 15 {
 16     int e,f,id;
 17     bool use;
 18     edge *next,*op;
 19 }*v[maxn],*vx[maxn],ed[(maxm+maxn+maxn)<<1];
 20 
 21 void add_edge(int s,int e,int f,int id)
 22 {
 23     en++;
 24     ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;v[s]->f=f;v[s]->id=id;
 25     en++;
 26     ed[en].next=v[e];v[e]=ed+en;v[e]->e=s;v[e]->f=0;v[e]->id=id;
 27     v[s]->op=v[e];v[e]->op=v[s];
 28 }
 29 
 30 void add_edge(int s,int e,int id)
 31 {
 32     en++;
 33     ed[en].next=vx[s];vx[s]=ed+en;vx[s]->e=e;vx[s]->use=false;vx[s]->id=id;
 34 }
 35 
 36 bool bfs()
 37 {
 38     memset(depth,0,sizeof(depth));
 39     depth[0]=1;
 40     int front=1,tail=1;
 41     q[1]=0;
 42     for (;front<=tail;)
 43     {
 44         int now=q[front++];
 45         for (edge *e=v[now];e;e=e->next)
 46             if (!depth[e->e] && e->f)
 47             {
 48                 depth[e->e]=depth[now]+1;
 49                 if (e->e==n+1) return true;
 50                 q[++tail]=e->e;
 51             }
 52     }
 53     return false;
 54 }
 55 
 56 int dfs(int now,int cur_flow)
 57 {
 58     if (now==n+1) return cur_flow;
 59     int rest=cur_flow;
 60     for (edge *e=v[now];e && rest;e=e->next)
 61         if (e->f && depth[e->e]==depth[now]+1)
 62         {
 63             int new_flow=dfs(e->e,min(rest,e->f));
 64             e->f-=new_flow;
 65             e->op->f+=new_flow;
 66             rest-=new_flow;
 67         }
 68     if (cur_flow==rest) depth[now]=-1;
 69     return cur_flow-rest;
 70 }
 71 
 72 int dinic()
 73 {
 74     int ans=0;
 75     while (bfs())
 76         ans+=dfs(0,INF);
 77     return ans;
 78 }
 79 
 80 bool check(int upper,int opt)
 81 {
 82     en=0;
 83     memset(v,0,sizeof(v));
 84     memset(in,0,sizeof(in));
 85     memset(out,0,sizeof(out));
 86     for (int a=1;a<=m;a++)
 87     {
 88         if (v1[a]<=upper) out[s[a]]++,in[t[a]]++;
 89         if (v2[a]<=upper) add_edge(s[a],t[a],1,a);
 90     }
 91     for (int a=1;a<=n;a++)
 92         if (abs(in[a]-out[a])&1) return false;
 93     int sum=0;
 94     for (int a=1;a<=n;a++)
 95     {
 96         int delta=in[a]-out[a];
 97         sum+=(delta > 0 ? (delta>>1) : 0);
 98         if (delta>0) add_edge(a,n+1,delta>>1,0);
 99         if (delta<0) add_edge(0,a,(-delta)>>1,0);
100     }
101     int flow=dinic();
102     if (sum!=flow) return false;
103     if (opt)
104     {
105         for (int a=1;a<=n;a++)
106             for (edge *e=v[a];e;e=e->next)
107                 if (e->e!=0 && e->e!=n+1 && e->f) add_edge(a,e->e,e->id);
108         for (int a=1;a<=m;a++)
109             if (v1[a]<=upper && v2[a]>upper) add_edge(s[a],t[a],a);
110         for (int a=1;a<=n;a++)
111             v[a]=vx[a];
112     }
113     return true;
114 }
115 
116 void dfs(int now)
117 {
118     for (edge *e=v[now];e;e=e->next)
119         if (!e->use)
120         {
121             e->use=true;
122             dfs(e->e);
123             res[++size]=e->id;
124         }
125 }
126 
127 int main()
128 {
129     freopen("bridges.in","r",stdin);
130     freopen("bridges.out","w",stdout);
131 
132     scanf("%d%d",&n,&m);
133     int l=INF,r=-INF;
134     for (int a=1;a<=m;a++)
135     {
136         scanf("%d%d%d%d",&s[a],&t[a],&v1[a],&v2[a]);
137         if (v1[a]>v2[a]) swap(v1[a],v2[a]),swap(s[a],t[a]);
138         l=min(l,v1[a]);
139         r=max(r,v2[a]);
140     }
141     l--;
142     while (l+1!=r)
143     {
144         int m=(l+r)>>1;
145         if (check(m,0)) r=m;
146         else l=m;
147     }
148     if (!check(r,1))
149     {
150         printf("NIE\n");
151         return 0;
152     }
153     printf("%d\n",r);
154     dfs(1);
155     for (int a=m;a>=1;a--)
156         printf("%d ",res[a]);
157     printf("\n");
158 
159     return 0;
160 }
View Code

 

Pilots:

单调队列……这玩意儿我居然想了那么久……

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 
 8 const int maxn=3000010;
 9 
10 int k,n,q1[maxn][2],q2[maxn][2];
11 
12 int main()
13 {
14     freopen("pilots.in","r",stdin);
15     freopen("pilots.out","w",stdout);
16 
17     scanf("%d%d",&k,&n);
18     int front1=1,tail1=0,front2=1,tail2=0,ans=1,p=1;
19     for (int a=1;a<=n;a++)
20     {
21         int v;
22         scanf("%d",&v);
23         while (front1<=tail1 && v<q1[tail1][0])
24             tail1--;
25         q1[++tail1][0]=v;q1[tail1][1]=a;
26         while (front2<=tail2 && v>q2[tail2][0])
27             tail2--;
28         q2[++tail2][0]=v;q2[tail2][1]=a;
29         while (abs(q1[front1][0]-q2[front2][0])>k)
30         {
31             p++;
32             while (q1[front1][1]<p)
33                 front1++;
34             while (q2[front2][1]<p)
35                 front2++;
36         }
37         ans=max(ans,a-p+1);
38     }
39     printf("%d\n",ans);
40 
41     return 0;
42 }
View Code

 

posted @ 2013-09-21 16:15  zhonghaoxi  阅读(837)  评论(0编辑  收藏  举报
BYRBT