我 是 个 傻 逼
T1
给你一个长度不超过10的数字串,问你可不可以加若干加号和一个等号使它变成一个等式
sol:
搜
T2
给一个01串,每个地方有一个代价$c_i$,交换两个字符的代价是$c_i + c_j$
求最后逆序对数 - 交换代价的最大值
$n \leq 1000$
sol:
首先想到,交换两个位置$(i,j)$ $(j > i)$对答案的贡献其实是$j - i - c_i - c_j$
于是我们可以想到一个贪心,每次从后往前找$1$,每找到一个$1$就从前往后找一个最优的$0$,然后交换
这样可以贪到80分
然后去问了管老师,管老师:多贪几次
我:.... %%%
正解其实是dp
每一个位置最多只会交换一次
我们可以记$f(i,j,k)$表示前$i$位已经确定,有$j$个位置从$1$变成了$0$,$k$个位置从$0$变成了$1$
转移的时候我们枚举$i + 1$是$0$还是$1$即可
发现并不需要记$j,k$具体值,只需要记$j-k$
于是就做完了
T3
一棵树,每个点上有一个灯,灯有开关,一开始全关着,树上有m个人,每个人有初始位置
你要维护:
1.让编号在$[l,r]$的人走到$x$点
2.让编号在$[l,r]$的人向根走$x$步,走到根就不走了
3.让编号为$x$的人按一下开关,并询问$x$子树里所有开灯的点到$x$的距离之和
sol:
分为两部分来做
1.维护每个人的位置,显然是一个线段树区间赋值 & 区间加
注意当区间赋值的时候要顺便把这个点的加法标记清除掉
2.按开关,询问子树开灯的点到这个点的距离和
我们可以按dfs序开两个树状数组表示子树权值和 & 子树内有多少个开灯的点
然后模拟即可
T2只贪了一次 = 80分
T3fa[1]没有设为1 = GG
于是180被爆踩
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<cstdio> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define mp make_pair #define pb push_back #define xx first #define yy second typedef long long ll; typedef pair<int,int> pii; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } const int maxn=10; char s[maxn]; int n; int solve() { scanf("%s",s+1); n=strlen(s+1); rep(x,1,n-1) { rep(S,0,(1<<n-1)-1) { int left=0,cur=0,right=0; rep(i,1,x) { cur=cur*10+s[i]-'0'; if(S>>i-1&1) left+=cur,cur=0; } left+=cur;cur=0; rep(i,x+1,n) { cur=cur*10+s[i]-'0'; if(S>>i-1&1) right+=cur,cur=0; } right+=cur;cur=0; if(left==right) return 1; } } return 0; } int main() { freopen("equation.in","r",stdin); freopen("equation.out","w",stdout); int T=read(); while(T--) puts(solve()?"Yes":"No"); return 0; }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<cstdio> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define mp make_pair #define pb push_back #define xx first #define yy second typedef long long ll; typedef pair<int,int> pii; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } const int maxn=2610; const int inf=1e9; int n,A[maxn]; int f[2][maxn*2];// (0 -> 1) - (1 -> 0) char p[maxn]; int main() { freopen("inverse.in","r",stdin); freopen("inverse.out","w",stdout); n=read(); scanf("%s",p+1); rep(i,1,n) A[i]=read(); rep(i,0,2*n) f[0][i]=-inf; f[0][n]=0;int cur=0,c1=0; rep(i,1,n) { cur^=1; rep(j,0,2*n) f[cur][j]=-inf; rep(j,0,2*n) { int& ans=f[cur^1][j];if(ans==-inf) continue; if(p[i]=='1') { f[cur][j]=max(f[cur][j],ans); f[cur][j-1]=max(f[cur][j-1],ans-A[i]+c1+j-n); } else { f[cur][j]=max(f[cur][j],ans+c1+j-n); f[cur][j+1]=max(f[cur][j+1],ans-A[i]); } } if(p[i]=='1') c1++; } printf("%d\n",f[cur][n]); return 0; }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<cstdio> #include<cstring> #include<cctype> #include<algorithm> #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } typedef long long ll; const int maxn=160010; int n,m,first[maxn],nxt[maxn<<1],to[maxn<<1],e; void AddEdge(int u,int v) { to[++e]=v;nxt[e]=first[u];first[u]=e; to[++e]=u;nxt[e]=first[v];first[v]=e; } int anc[maxn][20],dep[maxn],st[maxn],en[maxn],cnt; void dfs(int x) { st[x]=++cnt;dep[x]=dep[anc[x][0]]+1; rep(i,1,19) anc[x][i]=anc[anc[x][i-1]][i-1]; for(int i=first[x];i;i=nxt[i]) if(to[i]!=anc[x][0]) { anc[to[i]][0]=x;dfs(to[i]); } en[x]=cnt; } int swim(int x,int k) { k=min(k,dep[x]-1); dwn(i,19,0) if(k>>i&1) x=anc[x][i]; return x; } int addv[maxn<<2],setv[maxn<<2],p[maxn],A[maxn]; void build(int o,int l,int r) { if(l==r) setv[o]=p[l]; else { int mid=l+r>>1,lc=o<<1,rc=lc|1; build(lc,l,mid);build(rc,mid+1,r); } } void pushdown(int o) { int lc=o<<1,rc=lc|1; if(setv[o]) { addv[lc]=addv[rc]=0; setv[lc]=setv[rc]=setv[o]; setv[o]=0; } if(addv[o]) { addv[lc]+=addv[o]; addv[rc]+=addv[o]; addv[o]=0; } } void update(int o,int l,int r,int ql,int qr,int t,int v) {//t=1 -> set, t=2 -> add if(ql<=l&&r<=qr) { if(t==1) addv[o]=0,setv[o]=v; else addv[o]+=v; } else { pushdown(o); int mid=l+r>>1,lc=o<<1,rc=lc|1; if(ql<=mid) update(lc,l,mid,ql,qr,t,v); if(qr>mid) update(rc,mid+1,r,ql,qr,t,v); } } int query(int o,int l,int r,int p) { if(l==r) return swim(setv[o],addv[o]); pushdown(o); int mid=l+r>>1,lc=o<<1,rc=lc|1; if(p<=mid) return query(lc,l,mid,p); return query(rc,mid+1,r,p); } struct Fenwich { ll sumv[maxn]; Fenwich() {memset(sumv,0,sizeof(sumv));} void add(int x,int v) {for(;x<=n;x+=x&-x) sumv[x]+=v;} ll sum(int x) {ll res=0;for(;x;x-=x&-x) res+=sumv[x];return res;} }T1,T2; int main() { freopen("robot.in","r",stdin); freopen("robot.out","w",stdout); n=read();m=read(); rep(i,2,n) AddEdge(read(),read()); rep(i,1,m) p[i]=read(); dfs(1);build(1,1,m); dwn(i,read(),1) { int t=read(); if(t==1||t==2) { int l=read(),r=read(),x=read(); update(1,1,m,l,r,t,x); } else { int k=read(),x=query(1,1,m,k),v=(A[x]?-1:1); printf("%lld\n",T2.sum(en[x])-T2.sum(st[x]-1)-(ll)dep[x]*(T1.sum(en[x])-T1.sum(st[x]-1))); T1.add(st[x],v);T2.add(st[x],v*dep[x]); A[x]^=1; } } return 0; }