• NOIp2018集训test-9-19(am&pm)


    AM

    这是一套在长沙考过而且我能记得全部正解的题,然后期望得分300实际得分155。

    T1

    很套路,随便搞(我当年是怎么花大半场时间写T1并且写出现在两倍长的代码的??)

     1 //Achen
     2 #include<bits/stdc++.h>
     3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     5 #define Formylove return 0
     6 const int N=2e5+5;
     7 using namespace std;
     8 typedef long long LL;
     9 typedef double db;
    10 int n,m,cnt[62];
    11 LL a[N];
    12 
    13 template<typename T>void read(T &x) {
    14     T f=1; x=0; char ch=getchar();
    15     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    16     if(ch=='-') f=-1,ch=getchar();
    17     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    18 }
    19 
    20 map<LL,int>mp;
    21 
    22 LL mo(LL x,LL p) { return x>=p?x-p:x;}
    23 LL ksc(LL a,LL b,LL p) {
    24     if(a>=p) a%=p;
    25     if(b>=p) b%=p;
    26     if(a<b) swap(a,b);
    27     LL bs=a,rs=0;
    28     while(b) {
    29         if(b&1) rs=mo(rs+bs,p);
    30         bs=mo(bs+bs,p);
    31         b>>=1;
    32     }
    33     return rs;
    34 }
    35 
    36 #define ANS
    37 int main() {
    38 #ifdef ANS
    39     freopen("meaningless.in","r",stdin);
    40     freopen("meaningless.out","w",stdout);
    41 #endif
    42     read(n); read(m);
    43     For(i,1,n) {
    44         read(a[i]);
    45         For(j,0,59) if(a[i]&(1LL<<j)) 
    46             cnt[j]++;
    47         mp[a[i]]++;
    48     }
    49     For(i,1,m) {
    50         int o;
    51         LL x,y,p;
    52         read(o);
    53         if(o==1) {
    54             read(x); read(y);
    55             if(x==y) continue;
    56             if(mp[x]) {
    57                 int tp=mp[x];
    58                 For(j,0,59) {
    59                     if((x&(1LL<<j))&&!(y&(1LL<<j))) {
    60                         cnt[j]-=tp;
    61                     }
    62                     else if(!(x&(1LL<<j))&&(y&(1LL<<j))){
    63                         cnt[j]+=tp;
    64                     }
    65                 }
    66                 mp[y]+=tp;
    67                 mp[x]=0;
    68             }
    69         }
    70         else {
    71             read(p);
    72             LL bs=1LL,ans=0;
    73             For(i,0,59) {
    74                 ans=mo(ans+ksc((LL)cnt[i]*(n-cnt[i])*2,bs,p),p);
    75                 bs=bs*2LL%p;
    76             }
    77             printf("%lld
    ",ans);
    78         }
    79     }
    80     //cerr<<clock()<<endl;
    81     Formylove;
    82 }
    View Code

    T2

    一开始一直在想数位dp,事实证明当初我不会数位dp现在仍然不会,然后看了下lucas发现很好做啊,结果少了一句话——sum[0][0]没有赋值(手拍就是不靠谱),直接炸了45分。

     1 //Achen
     2 #include<bits/stdc++.h>
     3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     5 #define Formylove return 0
     6 const int N=1000007,p=2333;
     7 using namespace std;
     8 typedef long long LL;
     9 typedef double db;
    10 int T,C[p+2][p+2],sum[p+2][p+2];
    11 LL n,k,fac[N],inv[N];
    12 
    13 template<typename T>void read(T &x) {
    14     T f=1; x=0; char ch=getchar();
    15     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    16     if(ch=='-') f=-1,ch=getchar();
    17     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    18 }
    19 
    20 LL lucas(LL n,LL m) {
    21     if(n<p&&m<p) return C[n][m];
    22     return lucas(n/p,m/p)*lucas(n%p,m%p)%p;
    23 }
    24 
    25 LL calc(LL n,LL m) {
    26     if(n<=p&&m<=p) return sum[n][m];
    27     LL t1=m/p,t2=m%p,rs;
    28     if(t1) rs=calc(n/p,t1-1)*calc(n%p,2332)%p;
    29     else rs=0;
    30     rs=(rs+lucas(n/p,t1)*calc(n%p,t2)%p)%p;
    31     return rs;
    32 }
    33 
    34 #define ANS
    35 int main() {
    36 #ifdef ANS
    37     freopen("quondam.in","r",stdin);
    38     freopen("quondam.out","w",stdout);
    39 #endif
    40     read(T);
    41     For(i,0,p) C[i][0]=1;
    42     For(i,1,p) For(j,1,i) C[i][j]=(C[i-1][j-1]+C[i-1][j])%p;
    43     sum[0][0]=1;
    44     For(i,0,p) {
    45         sum[i][0]=1;
    46         For(j,1,p) sum[i][j]=(sum[i][j-1]+C[i][j])%p;
    47     }
    48     while(T--) {
    49         read(n); read(k);
    50         LL ans=calc(n,k);
    51         printf("%lld
    ",ans); 
    52     }
    53     //cerr<<clock()<<endl;
    54     Formylove;
    55 }
    View Code

    T3

    对这题影响贼深刻,打t2之前打的t3,以为稳了,结果直接爆0。一是我经常犯的一手写队列就出错,调用队首元素总是把que[ql]直接写成ql,二是写的时候不知为何没开滚动数组,而是把更新签到数组存下来(好像和滚动是一个意思来着,无所谓了),因为要插两次,第二次插之前就复原一次,结果如果k是1的话第一次是没插的,一复原就跳到原来去了,相当于滚动数组某次没做dp却把o^=1。

    一开始写的时候sb地把攻击力相同的点合并了,显然是不能合并的,因为种类不同,背包同种类之间是无差的。实际上有没有攻击力相同的点是无所谓的做法是相同的。

     1 //Achen
     2 #include<bits/stdc++.h>
     3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     5 #define Formylove return 0
     6 const int N=200007,P=19260817;
     7 using namespace std;
     8 typedef long long LL;
     9 typedef double db;
    10 int n,m,sa[N],tot,sumnow;
    11 LL ans,cc[N];
    12 
    13 template<typename T>void read(T &x) {
    14     T f=1; x=0; char ch=getchar();
    15     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    16     if(ch=='-') f=-1,ch=getchar();
    17     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    18 }
    19 
    20 struct node {
    21     int v,cnt;
    22     friend bool operator <(const node&A,const node&B) {
    23         return A.v>B.v;
    24     }
    25 }p[505];
    26 
    27 LL mo(LL x) { 
    28     if(x<0) {
    29         int debug=1;
    30     }
    31     return x<0?x+P:(x>=P?x-P:x); 
    32 }
    33 
    34 LL f[N],prf[N];
    35 int que[N],ql,qr;
    36 void ins(int v,int cnt) {
    37     if(!cnt) return;
    38     For(w,0,v-1) {
    39         ql=0; qr=-1;
    40         LL tp=0;
    41         for(int i=w;i<=m;i+=v) {
    42             while(ql<=qr&&(i-que[ql])/v>cnt) {
    43                 tp=mo(tp-prf[que[ql]]); ql++;
    44             }
    45             prf[i]=f[i]; 
    46             f[i]=mo(f[i]+tp);
    47             tp=mo(tp+prf[i]);
    48             que[++qr]=i; 
    49         }
    50     }
    51 }
    52 
    53 #define ANS
    54 int main() {
    55 #ifdef ANS
    56     freopen("refrigerator.in","r",stdin);
    57     freopen("refrigerator.out","w",stdout);
    58 #endif
    59     read(n); read(m);
    60     For(i,1,n) {
    61         read(p[i].cnt); read(p[i].v);
    62     }
    63     sort(p+1,p+n+1);
    64     For(i,1,n) sumnow+=p[i].cnt*p[i].v;
    65     f[0]=1;
    66     if(sumnow<m) ans++;
    67     For(i,1,n) {
    68         sumnow-=p[i].cnt*p[i].v;
    69         ins(p[i].v,p[i].cnt-1);
    70         For(s,max(0,m-sumnow-p[i].v),m-sumnow-1) 
    71             ans=mo(ans+f[s]);
    72         if(p[i].cnt-1) For(j,0,m) f[j]=prf[j];
    73         ins(p[i].v,p[i].cnt);
    74     }
    75     printf("%lld
    ",ans);
    76     //cerr<<clock()<<endl;
    77     Formylove;
    78 }
    View Code

    PM

    也是一年前做过的,太菜还是做不求来。

    T1segment

    两种做法,标解是个套路,把每个修改拆成左右两边然后按左边排序,遇见左端点就加进set遇见右端点就erase,每次遇见点的时候上个点到这个点的区间间的最大值就是set里的最大值。

    我忘了这个套路,然后很sb地把修改按a大小排序,从大到小覆盖区间,每个区间第一次被覆盖的时候就是它最后的答案。用set维护区间,一开始放进一个(1,n,未覆盖)的点,每次在set里把能覆盖的区间找出来,已经被覆盖的一段连续区间合并,复杂度就很ok。也还是很好写的,stl就是好。

    然而我一开始只有80pt,因为1e18的时候r-l已经是Longlong了没取膜,再乘一个int就爆了。

     1 //Achen
     2 #include<bits/stdc++.h>
     3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     5 #define Formylove return 0
     6 const int N=1e5+7,p=998244353;
     7 using namespace std;
     8 typedef long long LL;
     9 typedef double db;
    10 int m;
    11 LL n,ans;
    12 
    13 template<typename T>void read(T &x) {
    14     T f=1; x=0; char ch=getchar();
    15     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    16     if(ch=='-') f=-1,ch=getchar();
    17     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    18 }
    19 
    20 struct QS {
    21     LL l,r,a;
    22     friend bool operator <(const QS&A,const QS&B) {
    23         return A.a>B.a;
    24     }
    25 }q[N];
    26 
    27 struct node {
    28     LL l,r;
    29     int ok;
    30     node(){}
    31     node(LL l,LL r,int ok):l(l),r(r),ok(ok){}
    32     friend bool operator <(const node&A,const node&B) {
    33         return A.r<B.r;
    34     }
    35 };
    36 set<node>s;
    37 #define IT set<node>::iterator 
    38 LL mo(LL x) { return (x%p+p)%p; }
    39 LL pf(LL x) { return x*x%p; }
    40 
    41 #define ANS
    42 int main() {
    43 #ifdef ANS
    44     freopen("segment.in","r",stdin);
    45     freopen("segment.out","w",stdout);
    46 #endif
    47     read(n); read(m);
    48     For(i,1,m) {
    49         read(q[i].l); 
    50         read(q[i].r); 
    51         read(q[i].a);
    52     }
    53     sort(q+1,q+m+1);
    54      s.insert(node(1,n,0));
    55     For(i,1,m) {
    56         node t=node(q[i].l,q[i].r,0);
    57         node x;
    58         node nx=node(0,0,1),nl=node(0,0,0),nr=node(0,0,0);
    59         IT it=s.lower_bound(t);
    60         for(;;) {
    61             if(it==s.end()) break;
    62             x=*it;
    63             s.erase(it--);
    64             if(x.l>t.l&&x.r<t.r) {
    65                 if(!x.ok) ans=mo(ans+pf(q[i].a%p)*((x.r-x.l+1)%p)%p);
    66             }
    67             if(x.r>=t.r) {
    68                 if(!x.ok) ans=mo(ans+pf(q[i].a%p)*(((t.r-max(t.l,x.l)+1))%p)%p);
    69                 if(!x.ok&&x.r>t.r) {
    70                     nr=node(t.r+1,x.r,0);
    71                     nx.r=t.r;
    72                 }
    73                 else nx.r=x.r;
    74             }
    75             if(x.l<=t.l) {
    76                 if(!x.ok&&!(x.r>=t.r)) ans=mo(ans+pf(q[i].a%p)*((x.r-t.l+1)%p)%p);
    77                 if(!x.ok&&x.l<t.l) {
    78                     nl=node(x.l,t.l-1,0);
    79                     nx.l=t.l;
    80                 }
    81                 else nx.l=x.l;
    82                 break;
    83             }
    84         }
    85         if(nx.l!=0) s.insert(nx);
    86         if(nl.l!=0) s.insert(nl);
    87         if(nr.l!=0) s.insert(nr);
    88     }
    89     printf("%lld
    ",ans);
    90     //cerr<<clock()<<endl;
    91     Formylove;
    92 }
    View Code

    T2 hotel

    不知道为什么没有切这道题,有时候看到题觉得很麻烦就懒得动脑子去想,就想打个暴力部分分什么的就走,也可能没把题意理解清楚,看漏题上的条件之类的也是我经常犯的错误,题面往往是蕴含很多信息的,需要去理解,但我一看到不能秒懂的题面就会觉得头疼,这类题往往即使简单也做不出来。

    前30n^2模拟,中间30线段树维护非0区间的答案。其实读懂题这步就直接通向标解了。

    显然是把每个位置现在还能装多少人用线段树维护,题面告诉你这个东西非负,你把线段树区间维护非0段的信息改成维护非最小值的信息,随便处理一下就好了。

      1 //Achen
      2 #include<bits/stdc++.h>
      3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
      4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
      5 #define Formylove return 0
      6 const int N=3e5+7;
      7 using namespace std;
      8 typedef long long LL;
      9 typedef double db;
     10 int n,m,w[N];
     11 
     12 template<typename T>void read(T &x) {
     13     T f=1; x=0; char ch=getchar();
     14     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     15     if(ch=='-') f=-1,ch=getchar();
     16     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
     17 }
     18 
     19 LL sg[N<<2],mi[N<<2],lz[N<<2],sl[N<<2],sr[N<<2];
     20 #define lc (x<<1)
     21 #define rc ((x<<1)|1)
     22 #define mid ((l+r)>>1)
     23 LL get_all(LL l) { return (l+1)*l/2; }
     24 
     25 void down(int x,int l,int r) {
     26     if(!lz[x]) return;
     27     mi[lc]+=lz[x]; lz[lc]+=lz[x];
     28     mi[rc]+=lz[x]; lz[rc]+=lz[x];
     29     lz[x]=0;
     30 }
     31 
     32 void upd(int x,int l,int r) {
     33     if(mi[lc]==mi[rc]) {
     34         mi[x]=mi[lc];
     35         sg[x]=sg[lc]+sg[rc]+sr[lc]*sl[rc];
     36         sr[x]=(sr[rc]==r-mid?sr[lc]+r-mid:sr[rc]);
     37         sl[x]=(sl[lc]==mid-l+1?sl[rc]+mid-l+1:sl[lc]);
     38     }
     39     else if(mi[lc]<mi[rc]) {
     40         mi[x]=mi[lc]; sg[x]=sg[lc]+get_all(r-mid)+sr[lc]*(r-mid); 
     41         sl[x]=sl[lc]; sr[x]=sr[lc]+r-mid;
     42     }
     43     else {
     44         mi[x]=mi[rc]; sg[x]=sg[rc]+get_all(mid-l+1)+sl[rc]*(mid-l+1); 
     45         sr[x]=sr[rc]; sl[x]=sl[rc]+mid-l+1;
     46     } 
     47 }
     48 
     49 void build(int x,int l,int r) {
     50     if(l==r) { 
     51         sg[x]=sl[x]=sr[x]=0;
     52         mi[x]=w[l]; 
     53         return; 
     54     }
     55     build(lc,l,mid); build(rc,mid+1,r);
     56     upd(x,l,r);
     57 }
     58 
     59 void update(int x,int l,int r,int ql,int qr,LL w) {
     60     if(l>=ql&&r<=qr) { 
     61         mi[x]+=w; lz[x]+=w; return ;
     62     }
     63     down(x,l,r);
     64     if(ql<=mid) update(lc,l,mid,ql,qr,w);
     65     if(qr>mid) update(rc,mid+1,r,ql,qr,w);
     66     upd(x,l,r);
     67 }
     68 
     69 LL nlen;
     70 LL qry(int x,int l,int r,int ql,int qr) {
     71     if(l>=ql&&r<=qr) {
     72         if(mi[x]>0) { 
     73             LL rs=get_all(r-l+1)+nlen*(r-l+1);
     74             nlen+=(r-l+1);
     75             return rs;
     76         }
     77         LL rs=sg[x]+nlen*sl[x];
     78         if(sr[x]==r-l+1) nlen+=sr[x];
     79         else nlen=sr[x];
     80         return rs;    
     81     }
     82     down(x,l,r);
     83     LL rs=0;
     84     if(ql<=mid) rs+=qry(lc,l,mid,ql,qr);
     85     if(qr>mid) rs+=qry(rc,mid+1,r,ql,qr);
     86     return rs; 
     87 }
     88 
     89 #define ANS
     90 int main() {
     91 #ifdef ANS
     92     freopen("hotel.in","r",stdin);
     93     freopen("hotel.out","w",stdout);
     94 #endif
     95     read(n); read(m);
     96     For(i,1,n) read(w[i]);
     97     if(n<=-1000&&m<=-1000) {
     98         For(i,1,m) {
     99             int o,l,r,x;
    100             read(o); read(l); read(r);
    101             if(o==1) {
    102                 read(x);
    103                 For(j,l,r) w[j]-=x;
    104             }
    105             else {
    106                 LL tp=0,ans=0;
    107                 For(j,l,r) {
    108                     if(w[j]!=0) tp++;
    109                     else tp=0;
    110                     if(j==r||w[j+1]==0) 
    111                          ans+=(tp+1)*tp/2;
    112                 }
    113                 printf("%lld
    ",ans);
    114             }
    115         }
    116     }
    117     else {
    118         build(1,1,n);
    119         For(i,1,m) {
    120             int o,l,r,x;
    121             read(o); read(l); read(r);
    122             if(o==1) {
    123                 read(x);                
    124                 update(1,1,n,l,r,-x);
    125             }
    126             else {
    127                 nlen=0;
    128                 LL ans=qry(1,1,n,l,r);
    129                 printf("%lld
    ",ans);
    130             }
    131         }
    132     }
    133     //cerr<<clock()<<endl;
    134     Formylove;
    135 }
    View Code

    T3recursion

    我的数学很不好,对数字一类的东西总是很没有感觉,数学好能推柿子或者对数字有感觉的人这题应该是秒切的。但我打了半天表就只看出g是f的前缀和,硬是没看出g[g[]]是i*f的前缀和。

    现在还不会证,等ycl大佬分享吧。

    打表发现是前缀和以及f[i]代表i出现的次数,就随便搞了(有点像分块优化的感觉?)。

     1 //Achen
     2 #include<bits/stdc++.h>
     3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     5 #define Formylove return 0
     6 const int N=1e6+7,p=998244353;
     7 using namespace std;
     8 typedef long long LL;
     9 typedef double db;
    10 int n;
    11 int f[N];
    12 
    13 template<typename T>void read(T &x) {
    14     T f=1; x=0; char ch=getchar();
    15     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    16     if(ch=='-') f=-1,ch=getchar();
    17     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    18 }
    19 
    20 LL mo(LL x) { return x>=p?x-p:x; }
    21 
    22 int F(int n) {
    23     if(n==1) f[n]=1;
    24     if(!f[n]) {
    25         return 1+F(n-F(F(n-1)));
    26     }
    27     return f[n];
    28 }
    29 
    30 LL dc(LL l,LL r) { return (l+r)*(r-l+1)/2%p; }
    31 
    32 #define ANS
    33 int main() {
    34 #ifdef ANS
    35     freopen("recursion.in","r",stdin);
    36     freopen("recursion.out","w",stdout);
    37 #endif
    38     int tot=0;
    39     For(i,1,1000000) f[i]=F(i);
    40     read(n);
    41     int now=2;
    42     LL g=1,gg=1;
    43     for(int i=2;;i++) {
    44         if(now+f[i]>n) {
    45             g=mo(g+i*(n-now+1)%p);
    46             gg=mo(gg+i*dc(now,n)%p);
    47             break;
    48         }
    49         g=mo(g+i*f[i]%p);
    50         gg=mo(gg+i*dc(now,now+f[i]-1)%p);
    51         now+=f[i];
    52     }
    53     printf("%lld %lld
    ",g,gg);
    54     Formylove;
    55 }
    View Code
  • 相关阅读:
    BUAA 软工 | 从计算机技术中探索艺术之路
    好好编程BUAA_SE(组/团队) Scrum Meeting 博客汇总
    beta事后分析
    Beta阶段项目展示
    Beta阶段测试报告
    Beta版本发布计划
    Beta阶段 第十次Scrum Meeting
    Beta阶段 第九次Scrum Meeting
    Beta阶段 第八次Scrum Meeting
    Beta阶段 第七次Scrum Meeting
  • 原文地址:https://www.cnblogs.com/Achenchen/p/9678761.html
Copyright © 2020-2023  润新知