noip模拟68
A. 玩水
签到题.
A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
#define ll long long
#define ull unsigned ll
#define lf long double
#define lbt(x) (x&(-x))
#define mp(x,y) make_pair(x,y)
#define lb lower_bound
#define ub upper_bound
#define Fill(x,y) memset(x,y,sizeof x)
#define Copy(x,y) memcpy(x,y,sizeof x)
#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
inline ll read() {
ll res=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return cit?res:-res;
}
} using namespace BSS;
const ll N=3e3+21;
ll Ts,m,n;
ll c[N][N],dp[N][N];
inline bool check(ll x,ll y){
return c[x][y-1] and c[x-1][y] and c[x-1][y]==c[x][y-1];
}
inline bool Work(){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
dp[i][j]=max(dp[i-1][j-1]+check(i,j),max(dp[i-1][j],dp[i][j-1]));
if(check(i,j) and check(i-1,j)) return 1;
if(check(i,j) and check(i,j-1)) return 1;
}
}
return dp[n][m]>=2;
}
signed main(){
freopen("water.in","r",stdin),freopen("water.out","w",stdout);
Ts=read(); char s[N];
while(Ts--){
n=read(),m=read();
for(int i=1;i<=n;i++){
scanf("%s",s+1);
for(int j=1;j<=m;j++)
c[i][j]=s[j]-'a'+1;
}
printf("%d\n",(int)Work());
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
c[i][j]=0,dp[i][j]=0;
}
}
}
exit(0);
}
B. 假人
C. 切题
看起来确实是很网络流,每个 \(a\) 向每个 \(b\) 连一条边,如果流满那就是有解.
根据最大流最小割定理,把 \(a\) 从小到大排序,问题可以转化为:对于任意的 \(k\in [0, n]\),有\(\sum\limits_{i=1}^k a_i\le \sum\limits_{i=1}^m min(b_i,k)\)
发现右边的很难做,不难想到转化.
设 \(c_k\) 表示满足 \(b_i \ge k\) 的 \(b_i\) 个数。那么 \(\sum\limits_{i=1}^m min(b_i,k)=\sum\limits_{i=1}^k c_i\).
于是线段树维护就好了.
C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
#define ll long long int
#define ull unsigned ll
#define lf double
#define lbt(x) (x&(-x))
#define mp(x,y) make_pair(x,y)
#define lb lower_bound
#define ub upper_bound
#define Fill(x,y) memset(x,y,sizeof x)
#define Copy(x,y) memcpy(x,y,sizeof x)
#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
inline ll read() {
ll res=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return cit?res:-res;
}
} using namespace BSS;
#define ls (x<<1)
#define rs (x<<1|1)
const ll N=250021;
ll m,n,ops;
ll c[N],wa[N],rk[N],pa[N],pb[N],pos[N],prea[N],preb[N],prec[N];
struct I { ll w,id; } a[N],b[N];
struct II { ll minw,lzy; } tr[N<<2];
auto pushup=[](ll x)->void{ tr[x].minw=min(tr[ls].minw,tr[rs].minw); };
auto getval=[](ll x,ll w)->void{ tr[x].minw+=w,tr[x].lzy+=w; } ;
inline void spread(ll x,ll l,ll r){
ll &lzy=tr[x].lzy;
if(lzy) getval(ls,lzy),getval(rs,lzy),lzy=0;
}
void update(ll x,ll l,ll r,ll ql,ll qr,ll w){
if(ql>qr) return ;
if(l>=ql and r<=qr) return getval(x,w),void();
ll mid=(l+r)>>1; spread(x,l,r);
if(ql<=mid) update(ls,l,mid,ql,qr,w);
if(qr>mid) update(rs,mid+1,r,ql,qr,w);
pushup(x);
}
void build(ll x,ll l,ll r){
if(l==r) return tr[x].minw=prec[l]-prea[l],void();
ll mid=(l+r)>>1; spread(x,l,r);
build(ls,l,mid),build(rs,mid+1,r);
pushup(x);
}
inline void Swap(ll x,ll y){
ll idx=rk[x],idy=rk[y];
swap(wa[x],wa[y]),swap(rk[x],rk[y]),swap(pos[idx],pos[idy]);
}
signed main(){
File(problem);
n=read(),m=read();
for(int i=1;i<=n;i++) a[i].w=read(),a[i].id=i;
for(int i=1;i<=m;i++) b[i].w=read(),b[i].id=i;
sort(a+1,a+1+n,[](I i,I j)->bool{ return i.w==j.w ? i.id<j.id : i.w>j.w; });
sort(b+1,b+1+m,[](I i,I j)->bool{ return i.w==j.w ? i.id<j.id : i.w<j.w; });
for(int i=1;i<=m;i++) preb[i]=preb[i-1]+b[i].w;
for(int i=1,j=0;i<=n;i++){
while(j<m and b[j+1].w<i) j++;
c[i]=m-j,prec[i]=prec[i-1]+c[i];
prea[i]=prea[i-1]+a[i].w;
}
// for(int i=1;i<=m;i++) cout<<c[i]<<' '; puts("der");
sort(a+1,a+1+n,[](I i,I j)->bool{ return i.w==j.w ? i.id<j.id : i.w<j.w; });
sort(b+1,b+1+m,[](I i,I j)->bool{ return i.id<j.id; });
for(int i=1;i<=n;i++) pos[a[i].id]=i,rk[i]=a[i].id,wa[i]=a[i].w;
build(1,1,n),ops=read(); ll opt,x,y,z,w,p1,p2;
while(ops--){
opt=read(),x=read();
if(opt==1){
w=wa[pos[x]],p1=ub(wa+1,wa+1+n,w)-wa-1,p2=pos[x];
Swap(p1,p2); wa[p1]++,update(1,1,n,n-p1+1,n,-1);
}
if(opt==2){
w=wa[pos[x]],p1=lb(wa+1,wa+1+n,w)-wa,p2=pos[x];
Swap(p1,p2); wa[p1]--,update(1,1,n,n-p1+1,n,1);
}
if(opt==3){
if((++b[x].w)<=n) c[b[x].w]++,update(1,1,n,b[x].w,n,1);
}
if(opt==4){
if((b[x].w--)<=n) c[b[x].w+1]--,update(1,1,n,b[x].w+1,n,-1);
}
puts(tr[1].minw>=0 ? "1" : "0");
}
exit(0);
}
/*
2 20
14 20
29 28 22 8 16 30 4 13 30 17 22 1 19 5 3 13 17 16 3 27
*/