Codeforces Round #742 (Div. 2) ABCDE題解
阿新 • • 發佈:2021-09-06
A 水題:直接'U'對應'D','D'對應'U',遇見LR複製一遍。
B 比較簡單:預處理300000內的xor字首異或,當xor[a-1]==b,直接0-->a即可。否則,如果xor[a-1]^b==a,那麼需要0-->a-1以及另外兩個數字xor得到a(避免直接用a)故a+1個數,如果xor[a-1]^b!=a,那麼0-->a-1以及xor[a-1]^b這a+2個數。
C題:發現對於奇數位和雙數位上的數相加,他們是分別並且獨立的。例如15678 , 那麼分離開168和57,我們發現只有分別滿足兩個數加和為168和57即可,那麼他們方案數相乘。最後要減去2,因為有(0,數)和(數,0)的情況。
點選檢視程式碼
#include<iostream> #include<algorithm> #include<cstring> #include<stack> #include<bitset> #include<queue> #include<vector> #include<cstdio> #include<cmath> #define ll long long using namespace std; ll a[12],wz; ll ans; int main(){ int t; scanf("%d",&t); while (t--) { ll n; wz = 0; scanf("%lld",&n); ans = 1; while (n) { a[++wz] = n%10; n/=10; } ll ad = 0; ll af = 0; for(int i=wz;i>=1;i-=2) { ad = ad*10ll + a[i]; } for(int i=wz-1;i>=1;i-=2) { af = af*10ll + a[i]; } ans = (ad+1)*(af+1)-2; printf("%lld\n",ans); } return 0; }
D:其實就是一個模擬。。。我們發現只要拆分得儘可能不退位,退位先退低位就OK,程式碼寫得比較複雜。。
點選檢視程式碼
#include<iostream> #include<algorithm> #include<cstring> #include<stack> #include<bitset> #include<queue> #include<vector> #include<cstdio> #include<cmath> using namespace std; priority_queue<int,vector<int>,greater<int> > q; int S,N,wz; int a[15],po[15]; int main(){ po[1] = 1; for(int i=2;i<=10;i++) po[i] = po[i-1]*10; int t; scanf("%d",&t); while (t--) { wz = 0; scanf("%d%d",&S,&N); int sum = 0; while (S) { a[++wz] = S%10; S /= 10; sum += a[wz]; } if(sum>=N) { int hb = sum-N+1; int ans = 0; for(int i=1;i<=wz&&hb;i++) { while(a[i]&&hb) { hb--; ans += po[i]; a[i]--; } } printf("%d ",ans); N--; for(int i=1;i<=wz;i++) { while(a[i]) { printf("%d ",po[i]); a[i]--; } } puts(""); continue; } else { for(int i=2;i<=wz;i++) { for(int j=1;j<=a[i];j++) q.push(po[i]); } while(q.size()+a[1]<N) { int x = q.top(); q.pop(); if(x==10) a[1] += 10; else { for(int j=1;j<=10;j++) q.push(x/10); } } int ans = 0; while(a[1]&&a[1]+q.size()>N-1) { a[1]--; ans++; } while(q.size()>N-1) { ans += q.top(); q.pop(); } printf("%d ",ans); while(a[1]) { printf("1 "); a[1]--; } while(q.size()) { printf("%d ",q.top()); q.pop(); } puts(""); continue; } } return 0; }
發現一種驚為天人的寫法,還是太菜了(複製自xiaoziyao)
點選檢視程式碼
#include<stdio.h>
#include<math.h>
int T,n,m;
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<m;i++){
int j=pow(10,(int)log10(n-(m-i)));
printf("%d ",j),n-=j;
}
printf("%d\n",n);
}
return 0;
}
E:一道線段樹基本題吧,算是幫我徹徹底底地複習了一遍線段樹,也算是大有收穫吧。
本題開結構體記錄一段數列:1 字首連續最長不降 2 字尾連續最長不降 3 最左數 4 最右數 5該段包含答案對數 6該整段是否都是連續不降的
這樣轉移方式與維護方式就很簡單了,有點像小白逛公園。
點選檢視程式碼
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<bitset>
#include<queue>
#include<vector>
#include<cstdio>
#include<cmath>
#define ll long long
using namespace std;
const int maxn = 400005;
int n,q;
int a[maxn];
int tot,ls[maxn],rs[maxn],rt;
struct node {
int lonpre,lonsuf,ln,rn;
bool se;
ll tt;
}z[maxn];
void init(int p,int x) {
z[p].lonpre = z[p].lonsuf = z[p].se = z[p].tt = 1;
z[p].ln = z[p].rn = a[x];
}
node operator+(node aa,node bb) {
node cc;
if(aa.se&&bb.se&&aa.rn<=bb.ln) cc.se = 1; else cc.se = 0;
cc.lonpre = (aa.se&&aa.rn<=bb.ln) ? aa.lonpre + bb.lonpre : aa.lonpre;
cc.lonsuf = (bb.se&&aa.rn<=bb.ln) ? bb.lonsuf + aa.lonsuf : bb.lonsuf;
cc.tt = aa.tt + bb.tt + ( (aa.rn<=bb.ln) ? 1ll * aa.lonsuf * bb.lonpre : 0 ) ;
cc.ln = aa.ln; cc.rn = bb.rn;
return cc;
}
int maketree(int l,int r) {
int p = ++tot;
if(l==r) {
init(p,l);
return p;
}
int mid = (l+r)>>1;
ls[p] = maketree(l,mid);
rs[p] = maketree(mid+1,r);
z[p] = z[ls[p]] + z[rs[p]];
return p;
}
void update(int p,int l,int r,int x) {
if(l==r) {
init(p,l);
return;
}
int mid = (l+r)>>1;
if(x<=mid) update(ls[p],l,mid,x);
else update(rs[p],mid+1,r,x);
z[p] = z[ls[p]] + z[rs[p]];
}
node query(int p,int l,int r,int x,int y) {
if(x<=l&&r<=y) return z[p];
int mid = (l+r)>>1;
if(x>mid) return query(rs[p],mid+1,r,x,y);
else if(y<=mid) return query(ls[p],l,mid,x,y);
else return query(ls[p],l,mid,x,y) + query(rs[p],mid+1,r,x,y);
}
int main(){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++) {
scanf("%d",&a[i]);
}
rt = maketree(1,n);
int ty,x,y;
while(q--) {
scanf("%d%d%d",&ty,&x,&y);
if(ty==1) {
a[x] = y;
update(rt,1,n,x);
} else {
printf("%lld\n",query(rt,1,n,x,y).tt);
}
}
return 0;
}
F暫時待續吧。。。