• noip模拟测试42



    T1:世界线

      简单思考后会发现,每个点需要向它能到达(直接或间接)的所有点连边

      即:若点$i$能到达的点有$cnt_i$个,则答案为$sum _{i=1} ^{n} cnt_i - deg_{out} [i]$

      考虑用bitset维护每个点能到达的点集,发现空间卡不下,而时间有剩余

      于是用时间换空间,bitset的大小只开一半,然后跑两次算法,分别计算$1->n/2$与$n/2+1->n$的答案

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<cstdlib>
     6 #include<algorithm>
     7 #include<bitset>
     8 #include<queue>
     9 #define ll long long
    10 using namespace std;
    11 const int MAXN=60233,MAXM=100233;
    12 int n,m,h[MAXN],tot,deg[MAXN],du[MAXN],vis[MAXN];
    13 ll ans;
    14 struct node {
    15     int to,nxt;
    16 }mp[MAXM];
    17 bitset<30005> bt[MAXN],zero;
    18 queue<int> q;
    19 inline int R() {
    20     int a=0;char c=getchar();
    21     while(c>'9'||c<'0')c=getchar();
    22     while(c>='0'&&c<='9')a=a*10+c-'0',c=getchar();
    23     return a;
    24 }
    25 void add(int x,int y) {
    26     mp[++tot].nxt=h[x];
    27     mp[tot].to=y;
    28     h[x]=tot;
    29 }
    30 int main() {
    31     n=R();m=R();
    32     for(int i=1,aa,bb;i<=m;i++) {
    33         aa=R(),bb=R();
    34         add(aa,bb);++du[bb];
    35     }
    36     
    37     for(int i=1;i<=n;i++) {
    38         if(i<=n/2)bt[i][i]=1;
    39         deg[i]=du[i];
    40         if(!du[i]) q.push(i);
    41     }
    42     while(!q.empty()) {
    43         int u=q.front();q.pop();
    44         for(int i=h[u];i;i=mp[i].nxt) {
    45             int v=mp[i].to;
    46             bt[v]|=bt[u];
    47             if(!--deg[v]) q.push(v);
    48         }
    49     }
    50     for(int i=1;i<=n;i++)
    51         ans+=bt[i].count();
    52     
    53     for(int i=1;i<=n;i++) bt[i].reset();
    54     
    55     for(int i=1;i<=n;i++) {
    56         if(i>n/2)bt[i][i-n/2]=1;
    57         deg[i]=du[i];
    58         if(!du[i]) q.push(i);
    59     }
    60     while(!q.empty()) {
    61         int u=q.front();q.pop();
    62         for(int i=h[u];i;i=mp[i].nxt) {
    63             int v=mp[i].to;
    64             bt[v]|=bt[u];
    65             if(!--deg[v]) q.push(v);
    66         }
    67     }
    68     for(int i=1;i<=n;i++)
    69         ans+=bt[i].count();
    70     
    71     for(int i=1;i<=n;i++)
    72         ans-=(du[i]+1);
    73     
    74     printf("%lld
    ",ans);
    75     return 0;
    76 }
    t1 Code


    T2:时间机器

      深受网络流毒害……

      其实就是个简单的线段覆盖贪心,对左端点排序

      对于所有左端点小于当前线段的左端的区间,优先选择右端点较小的来覆盖当前线段

      用个set维护候选区间就行了

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<cstdlib>
     6 #include<algorithm>
     7 #include<set>
     8 using namespace std;
     9 const int MAXN=50233;
    10 int T,n,m,p,flag;
    11 inline int R() {
    12     int a=0;char c=getchar();
    13     while(c>'9'||c<'0')c=getchar();
    14     while(c>='0'&&c<='9')a=a*10+c-'0',c=getchar();
    15     return a;
    16 }
    17 struct point {
    18     int r,c;
    19     point(int _r,int _c) {
    20         r=_r,c=_c;
    21     }
    22     point() {r=c=0;}
    23 };
    24 bool operator < (const point &aa,const point &bb) {
    25     return aa.r<bb.r;
    26 }
    27 set<point> st;
    28 set<point>::iterator it;
    29 struct node {
    30     int l,r,s;
    31 }nd[MAXN],ri[MAXN];
    32 bool operator < (const node &aa,const node &bb) {
    33     if(aa.l!=bb.l) return aa.l<bb.l;
    34     return aa.r<bb.r;
    35 }
    36 int main() {
    37     T=R();
    38     while(T--) {
    39         st.clear();
    40         n=R(),m=R();
    41         for(int i=1;i<=n;i++) nd[i].l=R(),nd[i].r=R(),nd[i].s=R();
    42         for(int i=1;i<=m;i++) ri[i].l=R(),ri[i].r=R(),ri[i].s=R();
    43         sort(nd+1,nd+n+1),sort(ri+1,ri+m+1);
    44         int tp=1;
    45         for(int i=2;i<=n;i++) {
    46             if(nd[i].l==nd[tp].l&&nd[i].r==nd[tp].r) nd[tp].s+=nd[i].s;
    47             else nd[++tp]=nd[i];
    48         }
    49         n=tp;tp=1;
    50         for(int i=2;i<=m;i++) {
    51             if(ri[i].l==ri[tp].l&&ri[i].r==ri[tp].r) ri[tp].s+=ri[i].s;
    52             else ri[++tp]=ri[i];
    53         }
    54         m=tp;
    55         p=1;flag=0;
    56         for(int i=1;i<=n;i++) {
    57             for(;p<=m&&ri[p].l<=nd[i].l;++p)
    58                 st.insert(point(ri[p].r,ri[p].s));
    59             while(nd[i].s&&st.size()) {
    60                 it=st.lower_bound(point(nd[i].r,0));
    61                 if(it==st.end()) {nd[i].s=1;break;}
    62                 point tmp=*it;
    63                 st.erase(it);
    64                 if(tmp.c>nd[i].s) tmp.c-=nd[i].s,st.insert(tmp),nd[i].s=0;
    65                 else nd[i].s-=tmp.c;
    66             }
    67             if(nd[i].s) {flag=1;break;}
    68         }
    69         if(flag) printf("No
    ");
    70         else printf("Yes
    ");
    71     }
    72     return 0;
    73 }
    t2 Code


    T3:密码

      数位dp,太麻烦,不想说,先咕着

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<cstdlib>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #define ll long long
    10 using namespace std;
    11 const int MAXN=5000;
    12 const ll D=1e9+7;
    13 ll p,k,ans,f[MAXN][MAXN][2][2];
    14 ll dig[MAXN],tot,s[MAXN],len;
    15 char str[MAXN];
    16 void change() {
    17     len=strlen(str+1);
    18     for(int i=1;i<=len;i++) s[len-i+1]=str[i]-'0';
    19     while(len) {
    20         ll tmp=0;
    21         for(int i=len;i>=1;i--) {
    22             tmp=tmp*10+s[i];
    23             s[i]=tmp/p;
    24             tmp%=p;
    25         }
    26         dig[++tot]=tmp;
    27         while(!s[len]&&len) --len;
    28     }
    29 }
    30 void upt(ll &x,ll y) {
    31     x=(x+y)%D;
    32 }
    33 int main() {
    34     scanf("%s%lld%lld",str+1,&p,&k);
    35     change();
    36     f[tot+1][0][0][1]=1;
    37     ll k1=p*(p+1)/2%D,k2=(p-1)*p/2%D;
    38     for(int i=tot;i>=1;i--)
    39         for(int j=tot+1;j>=0;j--) {
    40             ll tk1=dig[i]*(dig[i]+1)/2%D,tk2=(dig[i]-1)*dig[i]/2%D;
    41             ll tk3=(dig[i]*(dig[i]-1)/2+dig[i]*(p-dig[i]+1))%D;
    42             ll tk4=((dig[i]+1)*dig[i]/2+(p-dig[i]-1)*dig[i])%D;
    43             upt(f[i][j][0][0],f[i+1][j][0][0]*k1);
    44             upt(f[i][j][1][0],f[i+1][j][0][0]*k2);
    45             upt(f[i][j][0][0],f[i+1][j][0][1]*tk1);
    46             upt(f[i][j][1][0],f[i+1][j][0][1]*tk2);
    47             upt(f[i][j][1][1],f[i+1][j][0][1]*dig[i]);
    48             upt(f[i][j][0][1],f[i+1][j][0][1]*(dig[i]+1));
    49             if(j) {
    50                 upt(f[i][j][1][0],f[i+1][j-1][1][0]*k1);
    51                 upt(f[i][j][1][0],f[i+1][j-1][1][1]*tk3);
    52                 upt(f[i][j][0][0],f[i+1][j-1][1][0]*k2);
    53                 upt(f[i][j][0][0],f[i+1][j-1][1][1]*tk4);
    54                 upt(f[i][j][1][1],f[i+1][j-1][1][1]*(p-dig[i]));
    55                 upt(f[i][j][0][1],f[i+1][j-1][1][1]*(p-dig[i]-1));
    56             }
    57         }
    58         //    for(int x=0;x<p;x++)
    59             //    for(int y=0;y<p;y++) {
    60                 //    if(x+y+1<p) {
    61                 //        upt(f[i][j][1][0],f[i+1][j][0][0]);
    62                 //        if(x+y<dig[i]) upt(f[i][j][0][0],f[i+1][j][0][1]);
    63                 //        if(x+y+1<dig[i]) upt(f[i][j][1][0],f[i+1][j][0][1]);
    64                 //    }
    65                 //    if(x+y<p) upt(f[i][j][0][0],f[i+1][j][0][0]);
    66                 //    if(j&&x+y+1>=p) {
    67                 //        upt(f[i][j][1][0],f[i+1][j-1][1][0]);
    68                 //        if(x+y+1-p<dig[i])
    69                 //            upt(f[i][j][1][0],f[i+1][j-1][1][1]);
    70                 //    }
    71                 //    if(j&&x+y>=p) {
    72                 //        upt(f[i][j][0][0],f[i+1][j-1][1][0]);
    73                 //        if(x+y-p<dig[i])
    74                 //            upt(f[i][j][0][0],f[i+1][j-1][1][1]);
    75                 //    }
    76                     
    77                 //    if(x+y+1==dig[i]) upt(f[i][j][1][1],f[i+1][j][0][1]);
    78                 //    if(x+y==dig[i]) upt(f[i][j][0][1],f[i+1][j][0][1]);
    79                 //    if(j&&x+y+1-p==dig[i])    upt(f[i][j][1][1],f[i+1][j-1][1][1]);
    80                 //    if(j&&x+y-p==dig[i]) upt(f[i][j][0][1],f[i+1][j-1][1][1]);
    81             //    }
    82     for(int i=k;i<=tot;i++) {
    83         upt(ans,f[1][i][0][0]);
    84         upt(ans,f[1][i][0][1]);
    85     }
    86     printf("%lld
    ",ans%D);
    87     return 0;
    88 }
    t3 Code

    (注释掉的是80分的暴力)



  • 相关阅读:
    在JavaWeb中使用Log4j步骤
    关于我为什么不再更新博客园了
    windows termial 配置文件
    windows10 命令行修复系统引导
    vscode修改code runner插件默认使用的编译器
    windows下vscode修复c++找不到头文件
    windows下安装mingw-w64
    vscode美化方法以及定制主题插件
    windows下隐藏磁盘分区
    2018 icpc 徐州网络赛 F Features Track
  • 原文地址:https://www.cnblogs.com/Gkeng/p/11509167.html
Copyright © 2020-2023  润新知