• 题解#3


    感觉自己弱得没救了。。。求神犇解救T_T

                                                                                                                          7

    2597: [Wc2007]剪刀石头布

    补集转化之后就是费用流了。我比较逗方案WA了两发。

     1 int n,m,k,mincost,tot=1,cnt,s,t,win[maxn],a[maxn][maxn],b[maxn][maxn],head[maxm],d[maxm],from[2*maxm];
     2   
     3 bool v[maxm];
     4   
     5 queue<int>q;
     6   
     7 struct edge{int from,go,next,v,c;}e[2*maxm];
     8   
     9 void add(int x,int y,int v,int c)
    10   
    11 {
    12   
    13     e[++tot]=(edge){x,y,head[x],v,c};head[x]=tot;
    14   
    15     e[++tot]=(edge){y,x,head[y],0,-c};head[y]=tot;
    16   
    17 }
    18   
    19 bool spfa()
    20   
    21 {
    22   
    23     for (int i=0;i<=cnt;i++){v[i]=0;d[i]=inf;}
    24   
    25     q.push(s);d[s]=0;v[s]=1;
    26   
    27     while(!q.empty())
    28   
    29     {
    30   
    31         int x=q.front();q.pop();v[x]=0;
    32   
    33         for (int i=head[x],y;i;i=e[i].next)
    34   
    35          if(e[i].v&&d[x]+e[i].c<d[y=e[i].go])
    36   
    37          {
    38   
    39             d[y]=d[x]+e[i].c;from[y]=i;
    40   
    41             if(!v[y]){v[y]=1;q.push(y);}
    42   
    43          }
    44   
    45     }
    46   
    47     return d[t]!=inf;
    48   
    49 }
    50   
    51 void mcf()
    52   
    53 {
    54   
    55     while(spfa())
    56   
    57     {
    58   
    59         int tmp=inf;
    60   
    61         for(int i=from[t];i;i=from[e[i].from]) tmp=min(tmp,e[i].v);
    62   
    63         mincost+=d[t]*tmp;
    64   
    65         for(int i=from[t];i;i=from[e[i].from]){e[i].v-=tmp;e[i^1].v+=tmp;}
    66   
    67     }
    68   
    69 }
    70   
    71 int main()
    72   
    73 {
    74     n=read();s=0;t=n+1;cnt=t;
    75     for5(n,n)a[i][j]=read(),win[i]+=(a[i][j]==1);
    76     for1(i,n)for1(j,i-1)if(a[i][j]==2)
    77     {
    78         add(s,++cnt,1,0);
    79         b[i][j]=tot+1;
    80         add(cnt,i,1,0);
    81         add(cnt,j,1,0);
    82     }
    83     for1(i,n)
    84     {
    85         mincost+=win[i]*(win[i]-1)/2;
    86         for2(j,win[i],n-2)add(i,t,1,j);
    87     }
    88     mcf();
    89     cout<<(n*(n-1)*(n-2)/6-mincost)<<endl;
    90     for1(i,n)for1(j,i-1)if(a[i][j]==2)a[i][j]=!e[b[i][j]].v,a[j][i]=!a[i][j];
    91     for1(i,n)for1(j,n)printf("%d%c",a[i][j],j==n?'
    ':' ');
    92   
    93     return 0;
    94   
    95 }  
    View Code

     3813: 奇数国

    果真良心送分题,随便写个线段树就可以过了。

     1 const int p[60]={2,3,5,7,11,13,17,19,23,29,
     2                 31,37,41,43,47,53,59,61,67,
     3                 71,73,79,83,89,97,101,103,
     4                 107,109,113,127,131,137,139,
     5                 149,151,157,163,167,173,179,
     6                 181,191,193,197,199,211,223,
     7                 227,229,233,239,241,251,257,
     8                 263,269,271,277,281};
     9 struct seg{int s[60];}t[4*maxn];
    10 int n=100000,ret,ans[60];
    11 inline void build(int k,int l,int r)
    12 {
    13     int mid=(l+r)>>1;t[k].s[1]=r-l+1;
    14     if(l==r)return;
    15     build(lch);build(rch);
    16 }
    17 inline void query(int k,int l,int r,int x,int y)
    18 {
    19     if(l==x&&r==y){for0(i,59)ans[i]+=t[k].s[i];return;}
    20     int mid=(l+r)>>1;
    21     if(y<=mid)query(lch,x,y);
    22     else if(x>mid)query(rch,x,y);
    23     else query(lch,x,mid),query(rch,mid+1,y);
    24 }
    25 inline void pushup(int k)
    26 {
    27     for0(i,59)t[k].s[i]=t[k<<1].s[i]+t[k<<1|1].s[i];
    28 }
    29 inline void change(int k,int l,int r,int x)
    30 {
    31     if(l==r){for0(i,59)t[k].s[i]=ans[i];return;}
    32     int mid=(l+r)>>1;
    33     if(x<=mid)change(lch,x);else change(rch,x);
    34     pushup(k);
    35 }
    36 inline int power(int x,int y)
    37 {
    38     int t=1;
    39     for(;y;y>>=1,x=(ll)x*x%mod)
    40         if(y&1)t=(ll)t*x%mod;
    41     return t;
    42 }
    43 
    44 int main()
    45 
    46 {
    47 
    48     freopen("input.txt","r",stdin);
    49 
    50     freopen("output.txt","w",stdout);
    51 
    52     build(1,1,n);
    53     int T=read();
    54     while(T--)
    55     {
    56         int ch=read(),x=read(),y=read(),ret=1;
    57         memset(ans,0,sizeof(ans));
    58         if(ch==0)
    59         {
    60             query(1,1,n,x,y);
    61             for0(i,59)if(ans[i])ret=(ll)ret*(p[i]-1)%mod*power(p[i],ans[i]-1)%mod;
    62             printf("%d
    ",ret);
    63         }else
    64         {
    65             for0(i,59)
    66             {
    67                 while(y%p[i]==0)ans[i]++,y/=p[i];
    68             }    
    69             change(1,1,n,x);
    70         }
    71     }
    72 
    73     return 0;
    74 
    75 }  
    View Code

     3870: Our happy ending

    T_T没想到状压DP,只想到了爆搜然后多重集合的排列数搞一下。。。没耐心写出来就翻题解了。。。

    看代码意思好像不能存在/取出1?

     1 int dp[1<<21];
     2 
     3 int main()
     4 
     5 {
     6 
     7     freopen("input.txt","r",stdin);
     8 
     9     freopen("output.txt","w",stdout);
    10 
    11     int T=read();
    12     while(T--)
    13     {
    14         int n=read(),l=read(),mx=read(),all=(1<<l)-1;
    15         memset(dp,0,sizeof(dp));
    16         dp[0]=1;
    17         for1(i,n)
    18          for3(j,all,0)if(dp[j])
    19           {
    20               int t=dp[j];
    21               for1(k,min(l,k))(dp[all&(j|(j<<k)|(1<<(k-1)))]+=t)%=mod;
    22               if(mx>l)dp[j]=(dp[j]+(ll)t*(mx-l)%mod)%mod;
    23           }
    24         int ans=0;
    25         for0(i,all)if(i&(1<<(l-1)))(ans+=dp[i])%=mod;
    26         cout<<ans<<endl;
    27     }
    28 
    29     return 0;
    30 
    31 }  
    View Code

    3826: [Usaco2014 Nov]Cow Jog

    我们发现如果两个人起始位置a<b,但终止位置b>a,那么这两人一定会撞车。

    所以按起始位置排序,发现就是要求最少单增子序列覆盖=最长不降子序列。

    然后就nlogn了。ll的问题WA了好几发。

     1 ll n,m,b[maxn];
     2 pa a[maxn];
     3 int main()
     4 {
     5     freopen("input.txt","r",stdin);
     6     freopen("output.txt","w",stdout);
     7     n=read();m=read();
     8     for1(i,n)a[i].first=read(),a[i].second=a[i].first+m*read();
     9     sort(a+1,a+n+1);
    10     for1(i,n)b[i]=inf;
    11     for1(i,n)b[upper_bound(b+1,b+n+1,-a[i].second)-b]=-a[i].second;
    12     for1(i,n)if(b[i]==inf)
    13     {
    14         cout<<i-1<<endl;
    15         return 0;
    16     }
    17     cout<<n<<endl;
    18     return 0;
    19 }
    View Code

    3825: [Usaco2014 Nov]Marathon

    线段树维护一下区间和和区间最大值就好了吧。1A+rank1实在不能再爽。

     1 struct seg{int sum,mx;}t[4*maxn];
     2 struct rec{int x,y;}a[maxn];
     3 inline int dist(rec a,rec b){return abs(a.x-b.x)+abs(a.y-b.y);}
     4 int n,m;
     5 inline void pushup(int k)
     6 {
     7     t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
     8     t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);
     9 }
    10 inline void build(int k,int l,int r)
    11 {
    12     if(l==r)
    13     {
    14         t[k].sum=dist(a[l],a[l-1]);
    15         t[k].mx=dist(a[l-1],a[l])+dist(a[l],a[l+1])-dist(a[l-1],a[l+1]);
    16         return;
    17     }
    18     build(lch);build(rch);
    19     pushup(k);
    20 }
    21 inline void change(int k,int l,int r,int x)
    22 {
    23     if(l==r)
    24     {
    25         t[k].sum=dist(a[l],a[l-1]);
    26         t[k].mx=dist(a[l-1],a[l])+dist(a[l],a[l+1])-dist(a[l-1],a[l+1]);
    27         return;
    28     }
    29     if(x<=mid)change(lch,x);else change(rch,x);
    30     pushup(k);
    31 }
    32 inline int getmax(int k,int l,int r,int x,int y)
    33 {
    34     if(l==x&&r==y)return t[k].mx;
    35     if(y<=mid)return getmax(lch,x,y);
    36     else if(x>mid)return getmax(rch,x,y);
    37     else return max(getmax(lch,x,mid),getmax(rch,mid+1,y));
    38 }
    39 inline int getsum(int k,int l,int r,int x,int y)
    40 {
    41     if(l==x&&r==y)return t[k].sum;
    42     if(y<=mid)return getsum(lch,x,y);
    43     else if(x>mid)return getsum(rch,x,y);
    44     else return getsum(lch,x,mid)+getsum(rch,mid+1,y);
    45 }
    46 int main()
    47 {
    48     freopen("input.txt","r",stdin);
    49     freopen("output.txt","w",stdout);
    50     n=read();m=read();
    51     for1(i,n)a[i].x=read(),a[i].y=read();
    52     build(1,1,n);
    53     while(m--)
    54     {
    55         char ch=getchar();
    56         while(ch!='U'&&ch!='Q')ch=getchar();
    57         if(ch=='Q')
    58         {
    59             int x=read(),y=read();
    60             if(x+1<=y-1)printf("%d
    ",getsum(1,1,n,x+1,y)-getmax(1,1,n,x+1,y-1));
    61             else if(x+1==y)printf("%d
    ",dist(a[x],a[y]));
    62             else printf("%d
    ",0);
    63         }
    64         else
    65         {
    66             int x=read();
    67             a[x].x=read();a[x].y=read();
    68             change(1,1,n,x);
    69             if(x>1)change(1,1,n,x-1);
    70             if(x<n)change(1,1,n,x+1);
    71         }
    72     }
    73     return 0;
    74 }
    View Code

    1052: [HAOI2007]覆盖问题

    hzwer:

    把所有的点用一个最小的矩形圈起来,显然第一个正方形摆在四个角其中的一个,

    删去它覆盖的点后,剩下的点变成一个子问题,再放一次正方形,判断下剩下的点是否在一个正方形内

    复杂度On

     1 struct rec{int x[maxn],y[maxn],top;}a,b;
     2 int n,mid;
     3 inline void cut(int x1,int x2,int y1,int y2)
     4 {
     5     int cnt=0;
     6     for1(i,b.top)
     7     if(b.x[i]<x1||b.x[i]>x2||b.y[i]<y1||b.y[i]>y2)b.x[++cnt]=b.x[i],b.y[cnt]=b.y[i];
     8     b.top=cnt;
     9 }
    10 inline void solve(int x)
    11 {
    12     int x1=inf,y1=inf,x2=-inf,y2=-inf;
    13     for1(i,b.top)
    14     {
    15           x1=min(x1,b.x[i]);x2=max(x2,b.x[i]);
    16           y1=min(y1,b.y[i]);y2=max(y2,b.y[i]);
    17     }
    18     if(x==1)cut(x1,x1+mid,y1,y1+mid);
    19     if(x==2)cut(x1,x1+mid,y2-mid,y2);
    20     if(x==3)cut(x2-mid,x2,y1,y1+mid);
    21     if(x==4)cut(x2-mid,x2,y2-mid,y2);
    22 }    
    23 inline bool check()
    24 {
    25     for1(x,4)
    26      for1(y,4)
    27       {
    28           b.top=a.top;
    29           for1(i,b.top)b.x[i]=a.x[i],b.y[i]=a.y[i];
    30           solve(x);solve(y);
    31           int x1=inf,y1=inf,x2=-inf,y2=-inf;
    32           for1(i,b.top)
    33           {
    34               x1=min(x1,b.x[i]);x2=max(x2,b.x[i]);
    35               y1=min(y1,b.y[i]);y2=max(y2,b.y[i]);
    36           }
    37           if(x2-x1<=mid&&y2-y1<=mid)return 1;
    38       }
    39     return 0;
    40 }
    41 int main()
    42 {
    43     freopen("input.txt","r",stdin);
    44     freopen("output.txt","w",stdout);
    45     a.top=n=read();
    46     for1(i,n)a.x[i]=read(),a.y[i]=read();
    47     int l=0,r=inf;
    48     while(l<=r)
    49     {
    50        mid=(l+r)>>1; 
    51        if(check())r=mid-1;else l=mid+1;
    52     }
    53     cout<<l<<endl;
    54     return 0;
    55 }
    View Code

    3251: 树上三角形

    大于50个点直接输出Y,否则暴力。

     我TM就是个sb,还写了倍增。

     1 int tot,head[maxn],n,m,dep[maxn],a[maxn],b[maxn],f[maxn][21];
     2 struct edge{int go,next;}e[maxn];
     3 inline void add(int x,int y)
     4 {
     5     e[++tot]=(edge){y,head[x]};head[x]=tot;
     6 }
     7 inline void dfs(int x)
     8 {
     9     for1(i,20)if(dep[x]>=1<<i)f[x][i]=f[f[x][i-1]][i-1];else break;
    10     for4(i,x)
    11     {
    12         dep[y]=dep[x]+1;f[y][0]=x;dfs(y);
    13     }
    14 }
    15 inline int lca(int x,int y)
    16 {
    17     if(dep[x]<dep[y])swap(x,y);
    18     int t=dep[x]-dep[y];
    19     for0(i,20)if(t&(1<<i))x=f[x][i];
    20     if(x==y)return x;
    21     for3(i,20,0)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
    22     return f[x][0];
    23 }
    24 int main()
    25 {
    26     freopen("input.txt","r",stdin);
    27     freopen("output.txt","w",stdout);
    28     n=read();m=read();
    29     for1(i,n)a[i]=read();
    30     for1(i,n-1){int x=read(),y=read();add(x,y);}
    31     dep[1]=1;
    32     dfs(1);
    33     while(m--)
    34     {
    35         int ch=read(),x=read(),y=read();
    36         if(ch==1)a[x]=y;
    37         else
    38         {
    39             int t=lca(x,y);
    40             if(dep[x]-dep[t]+dep[y]-dep[t]+1>=50)puts("Y");
    41             else
    42             {
    43                 int cnt=0;
    44                 for(int i=x;i!=t;i=f[i][0])b[++cnt]=a[i];
    45                 for(int i=y;i!=t;i=f[i][0])b[++cnt]=a[i];
    46                 b[++cnt]=a[t];
    47                 sort(b+1,b+cnt+1);
    48                 bool flag=0;
    49                 for2(i,3,cnt)if((ll)b[i]<(ll)b[i-1]+b[i-2]){flag=1;break;}
    50                 puts(flag?"Y":"N");
    51             }
    52         }
    53     }
    54     return 0;
    55 }
    View Code
  • 相关阅读:
    Tar命令用法详解
    一次Linux系统被攻击的分析过程
    企业系统安全管理和强化的十点建议
    中型企业的IT运维策略
    企业邮件服务器被列入RBL,申请撤销PBL指控
    Xshell远程连接Ubuntu
    LeetCode 7: Reverse Integer
    LeetCode 14: Longest Common Prefix
    LeetCode 203:Remove Linked List Elements
    数据挖掘之处理分类自变量与处理时间变量
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4242362.html
Copyright © 2020-2023  润新知