Codeforces Round #742 (Div. 2) ABCDE题解
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暂时待续吧。。。