LOJ#3101. 「JSOI2019」精准预测

传送门

对每个点定义(u,t,0/1)为编号为u的人在t时刻是活/死。

当u在t时刻死亡,那他在t+1时刻也必然死亡,(u,1,t)->(u,1,t+1)

当u在t+1时刻活着,那他必然在t时刻也活着,(u,0,t)->(u,0,t-1)

再对两个限制条件分别连边,

限制1:

(t,x,1)(t+1,y,1)(t+1,y,0)(t,x,0)

限制2:

(t,x,0)(t,y,1),(t,y,0)(t,x,1)

要求的是对一个点u在T+1时与他一起存活的人。不难转化为一个传递闭包问题。

从以上连边发现,生情况与死情况分别在内部连边,而只有生->死的边没有死->生的边。

所以原图是拓扑图所以我们的问题变成了对于每一个(x,0,T+1)求出它能够到达的所有(y,1,T+1)的状态数。

画出图,不难发现大量出度为一的点无用,于是可以把这些点全部去掉,也就等价于只留下T+1时刻的点与限制边的出点。

此时只有(2n+2m)个点,于是用bitset优化一下即可。。。

代码:

 

  1 //Copyright@3_soon,From Hangzhou No.2 High School Baimahu
  2 //Problem:
  3 //Result:
  4 #pragma GCC optimize(3)
  5 #include<bits/stdc++.h>
  6 using namespace std;
  7 #define re register
  8 #define LL long long
  9 #define DB double
 10 #define il inline
 11 #define For(x,a,b) for(re int x=a;x<=b;x++)
 12 #define For2(x,a,b) for(re int x=a;x>=b;x--)
 13 #define LFor(x,a,b) for(re LL x=a;x<=b;x++)
 14 #define LFor2(x,a,b) for(re LL x=a;x>=b;x--)
 15 #define Abs(x) ((x>0)? x:-x)
 16 #define pii pair<int,int>
 17 #define mp(x,y) make_pair(x,y)
 18 #define mod (LL)1000000007
 19 #define base 10500
 20 int gi()
 21 {
 22     int res=0,fh=1;char ch=getchar();
 23     while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
 24     if(ch=='-') fh=-1,ch=getchar();
 25     while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
 26     return fh*res;
 27 }
 28 LL gl()
 29 {
 30     LL res=0,fh=1;char ch=getchar();
 31     while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
 32     if(ch=='-') fh=-1,ch=getchar();
 33     while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
 34     return fh*res;
 35 }
 36 namespace IO{
 37 #define BUF_SIZE 100000
 38 #define OUT_SIZE 100000
 39 #define ll long long
 40     //fread->read
 41 
 42     bool IOerror=0;
 43     inline char nc(){
 44         static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
 45         if (p1==pend){
 46             p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
 47             if (pend==p1){IOerror=1;return -1;}
 48             //{printf("IO error!\n");system("pause");for (;;);exit(0);}
 49         }
 50         return *p1++;
 51     }
 52     inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
 53     inline void read(int &x){
 54         bool sign=0; char ch=nc(); x=0;
 55         for (;blank(ch);ch=nc());
 56         if (IOerror)return;
 57         if (ch=='-')sign=1,ch=nc();
 58         for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
 59         if (sign)x=-x;
 60     }
 61     inline void read(ll &x){
 62         bool sign=0; char ch=nc(); x=0;
 63         for (;blank(ch);ch=nc());
 64         if (IOerror)return;
 65         if (ch=='-')sign=1,ch=nc();
 66         for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
 67         if (sign)x=-x;
 68     }
 69     inline void read(double &x){
 70         bool sign=0; char ch=nc(); x=0;
 71         for (;blank(ch);ch=nc());
 72         if (IOerror)return;
 73         if (ch=='-')sign=1,ch=nc();
 74         for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
 75         if (ch=='.'){
 76             double tmp=1; ch=nc();
 77             for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
 78         }
 79         if (sign)x=-x;
 80     }
 81     inline void read(char *s){
 82         char ch=nc();
 83         for (;blank(ch);ch=nc());
 84         if (IOerror)return;
 85         for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
 86         *s=0;
 87     }
 88     inline void read(char &c){
 89         for (c=nc();blank(c);c=nc());
 90         if (IOerror){c=-1;return;}
 91     }
 92     //fwrite->write
 93     struct Ostream_fwrite{
 94         char *buf,*p1,*pend;
 95         Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
 96         void out(char ch){
 97             if (p1==pend){
 98                 fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
 99             }
100             *p1++=ch;
101         }
102         void print(int x){
103             static char s[15],*s1;s1=s;
104             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
105             while(x)*s1++=x%10+'0',x/=10;
106             while(s1--!=s)out(*s1);
107         }
108         void println(int x){
109             static char s[15],*s1;s1=s;
110             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
111             while(x)*s1++=x%10+'0',x/=10;
112             while(s1--!=s)out(*s1); out('\n');
113         }
114         void print(ll x){
115             static char s[25],*s1;s1=s;
116             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
117             while(x)*s1++=x%10+'0',x/=10;
118             while(s1--!=s)out(*s1);
119         }
120         void println(ll x){
121             static char s[25],*s1;s1=s;
122             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
123             while(x)*s1++=x%10+'0',x/=10;
124             while(s1--!=s)out(*s1); out('\n');
125         }
126         void print(double x,int y){
127             static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,
128                              1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,
129                              100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
130             if (x<-1e-12)out('-'),x=-x;x*=mul[y];
131             ll x1=(ll)floor(x); if (x-floor(x)>=0.5)++x1;
132             ll x2=x1/mul[y],x3=x1-x2*mul[y]; print(x2);
133             if (y>0){out('.'); for (size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i); print(x3);}
134         }
135         void println(double x,int y){print(x,y);out('\n');}
136         void print(char *s){while (*s)out(*s++);}
137         void println(char *s){while (*s)out(*s++);out('\n');}
138         void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
139         ~Ostream_fwrite(){flush();}
140     }Ostream;
141     inline void print(int x){Ostream.print(x);}
142     inline void println(int x){Ostream.println(x);}
143     inline void print(char x){Ostream.out(x);}
144     inline void println(char x){Ostream.out(x);Ostream.out('\n');}
145     inline void print(ll x){Ostream.print(x);}
146     inline void println(ll x){Ostream.println(x);}
147     inline void print(double x,int y){Ostream.print(x,y);}
148     inline void println(double x,int y){Ostream.println(x,y);}
149     inline void print(char *s){Ostream.print(s);}
150     inline void println(char *s){Ostream.println(s);}
151     inline void println(){Ostream.out('\n');}
152     inline void flush(){Ostream.flush();}
153 #undef ll
154 #undef OUT_SIZE
155 #undef BUF_SIZE
156 };
157 using namespace IO;
158 bitset<base>f[600005],g;
159 vector<int>p[50005][2],tim[50005];
160 int xx[100005],yy[100005],opt[100005];
161 int t[100005];
162 int n,m,T;
163 int cnt,tot,ans[100005];
164 int vis[500005];
165 int flag[100005];
166 struct pp{int to,nxt;}e[700005];
167 int head[500005];
168 void addedge(int x,int y){e[++tot]=(pp){y,head[x]};head[x]=tot;}
169 int getpos(int x,int y)
170 {
171     int l,r;
172     l=0,r=tim[x].size()-1;
173     while(l<=r)
174     {
175         re int mid=l+r>>1;
176         if(tim[x][mid]==y) return mid;
177         if(tim[x][mid]<y) l=mid+1;
178         else r=mid;
179     }
180     return 0;
181 }
182 void sfd(int u)
183 {
184     if(vis[u]) return;
185     vis[u]=1;
186     for(int i=head[u];i;i=e[i].nxt)
187         sfd(e[i].to),f[u]|=f[e[i].to];
188 }
189 void solve(int l,int r)
190 {
191     g.reset();
192     if(l>n) return ;
193     r=min(r,n);
194     For(i,1,cnt) vis[i]=0,f[i].reset();
195     For(i,l,r) For(j,0,tim[i].size()-1) f[p[i][1][j]][i-l]=1;
196     For(i,1,n) sfd(p[i][0][tim[i].size()-1]);
197     For(i,l,r)
198     {
199         if(f[p[i][0][tim[i].size()-1]][i-l]) g[i-l]=1,flag[i]=1;
200     }
201     For(i,1,n)
202     {
203         if(flag[i]) continue;
204         int u=p[i][0][tim[i].size()-1];
205         ans[i]+=(f[u]|g).count();
206     }
207 }
208 
209 
210 int main()
211 {
212     tot=cnt=0;
213     memset(ans,0,sizeof(ans));
214     memset(head,-1,sizeof(head));
215     memset(flag,0,sizeof(flag));
216     read(T),read(n),read(m);
217     For(i,1,m)
218     {
219         read(opt[i]),read(t[i]),read(xx[i]),read(yy[i]);
220         tim[xx[i]].push_back(t[i]);
221         tim[yy[i]].push_back(t[i]+(opt[i]^1));
222     }
223     For(i,1,n)
224     {
225         tim[i].push_back(T+1);
226         sort(tim[i].begin(),tim[i].end());
227         tim[i].erase(unique(tim[i].begin(),tim[i].end()),tim[i].end());
228         For(j,0,tim[i].size()-1)
229             p[i][0].push_back(++cnt),p[i][1].push_back(++cnt);
230     }
231     For(i,1,n)
232     {
233         For(j,1,tim[i].size()-1)
234         {
235             addedge(p[i][0][j],p[i][0][j-1]);
236             addedge(p[i][1][j-1],p[i][1][j]);
237         }
238     }
239     For(i,1,m)
240     {
241         int u=getpos(xx[i],t[i]),v;
242         if(!opt[i])
243         {
244             v=getpos(yy[i],t[i]+1);
245             addedge(p[xx[i]][1][u],p[yy[i]][1][v]);addedge(p[yy[i]][0][v],p[xx[i]][0][u]);
246         }
247         else
248         {
249             v=getpos(yy[i],t[i]);
250             addedge(p[xx[i]][0][u],p[yy[i]][1][v]);addedge(p[yy[i]][0][v],p[xx[i]][1][u]);
251         }
252     }
253     For(i,1,5) solve(base*(i-1)+1,base*i);
254     For(i,1,n) printf("%d ",flag[i]? 0:n-(ans[i]+1));
255     puts("");
256     return 0;
257 }
View Code

 

 

 

posted @ 2019-11-11 14:40  3_soon  阅读(190)  评论(0编辑  收藏  举报