zoukankan      html  css  js  c++  java
  • 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!
    ");system("pause");for (;;);exit(0);}
     49         }
     50         return *p1++;
     51     }
     52     inline bool blank(char ch){return ch==' '||ch=='
    '||ch=='
    '||ch=='	';}
     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('
    ');
    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('
    ');
    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('
    ');}
    136         void print(char *s){while (*s)out(*s++);}
    137         void println(char *s){while (*s)out(*s++);out('
    ');}
    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('
    ');}
    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('
    ');}
    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
  • 相关阅读:
    Jzoj1307 Jail
    Jzoj1307 Jail
    Jzoj1306 Sum
    Jzoj1306 Sum
    Jzoj1279 解题
    Jzoj1279 解题
    Jzoj1277最高的奶牛
    Jzoj1277最高的奶牛
    Jzoj1155 有根树的同构(树的Rabin-Karp)
    Jzoj1155 有根树的同构(树的Rabin-Karp)
  • 原文地址:https://www.cnblogs.com/3soon/p/11834765.html
Copyright © 2011-2022 走看看