zoukankan      html  css  js  c++  java
  • [cf1495E]Qingshan and Daniel

    选择其中卡片总数较少的一类,当相同时选择$t_{1}$所对应的一类(以下记作$A$类)

    如果$t_{1}$不是$A$类,就先对$t_{1}$操作一次(即令$a_{1}$减少1)

    下面,问题即不断删去$A$类中的一张卡片,再删除另一类中的一张卡片,直至$A$中卡片被删光

    事实上,$A$类中卡片删除顺序与最终另一类卡片剩余卡片的位置无关,具体证明考虑交换$A$中两张相邻卡片的删除顺序,并分类讨论来说明不影响即可

    由此,不妨假设$A$类卡片是从左到右依次删除(即删完一叠后删除下一叠),每一张删除时都找到下一叠未完全删除的非$A$类卡片,并删除其中一张

    对于这个过程,可以用下述方法维护:

    记录一个变量$s$,表示$A$中当前还有几张卡片没有对应的删除

    若当前为$A$类,令$s$加上这一叠的卡片数

    若当前为$B$类,从中删除$min(s,这一叠的卡片数)$,同时$s$也减去这个值

    由于是环,所以重复一次即可

    时间复杂度为$o(n)$,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 5000005
     4 #define mod 1000000007
     5 #define ll long long
     6 int n,m,p,x,y,seed,base,a[N],t[N],ans[N];
     7 ll s,tot[3];
     8 int rnd(){
     9     int ans=seed;
    10     seed=(1LL*seed*base+233)%mod;
    11     return ans;
    12 }
    13 int main(){
    14     scanf("%d%d",&n,&m);
    15     int lst=0;
    16     for(int i=1;i<=m;i++){
    17         scanf("%d%d%d%d",&x,&y,&seed,&base);
    18         for(int j=lst+1;j<=x;j++){
    19             t[j]=rnd()%2+1;
    20             a[j]=rnd()%y+1;
    21         }
    22         lst=x;
    23     }
    24     for(int i=1;i<=n;i++)tot[t[i]]+=a[i];
    25     if (tot[1]!=tot[2]){
    26         if (tot[1]<tot[2])p=1;
    27         else p=2;
    28     }
    29     else p=t[1];
    30     if (p!=t[1]){
    31         a[1]--;
    32         ans[1]++;
    33     }
    34     for(int i=1;i<=n;i++)
    35         if (t[i]==p){
    36             s+=a[i];
    37             ans[i]+=a[i];
    38             a[i]=0;
    39         }
    40         else{
    41             int x=min((ll)a[i],s);
    42             ans[i]+=x;
    43             s-=x;
    44             a[i]-=x;
    45         }
    46     for(int i=1;i<=n;i++)
    47         if (t[i]==p){
    48             s+=a[i];
    49             ans[i]+=a[i];
    50             a[i]=0;
    51         }
    52         else{
    53             int x=min((ll)a[i],s);
    54             ans[i]+=x;
    55             s-=x;
    56             a[i]-=x;
    57         }
    58     ans[0]=1;
    59     for(int i=1;i<=n;i++)ans[0]=((ans[i]^(1LL*i*i))+1)%mod*ans[0]%mod;
    60     printf("%d",ans[0]);
    61 } 
    View Code
  • 相关阅读:
    样式表中!important的用法
    ORA27101: shared memory realm does not exist问题的解决
    重置标识列的当前值
    ASP.NET Oracle数据库使用事务时注意事项
    Oracle中约束的添加方法总结
    HTML段落自动换行的样式设置
    ASP.NET应用程序中的服务器错误
    oracle中的rownum、order by与分页
    position:relative与float的区别
    Moss/Sharepoint 备份或还原时出错的处理(持续更新)
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14738713.html
Copyright © 2011-2022 走看看