【省選模擬】20/05/05

  • AA:按度數分塊即可
#include<bits/stdc++.h>
#define cs const
#define pb push_back
#define fi first
#define se second
using namespace std;
namespace IO{
	cs int Rlen=1<<22|1;
	inline char gc(){
		static char buf[Rlen],*p1,*p2;
		(p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin));
		return p1==p2?EOF:*p1++;
	} int read(){
		int x=0; char c=gc(); bool f=false;
		while(!isdigit(c)) f=c=='-', c=gc();
		while(isdigit(c)) x=(((x<<2)+x)<<1)+(c^48), c=gc();
		return f?-x:x;
	}
} using namespace IO;
typedef long long ll;
typedef pair<int, int> pi;
cs int N = 1e5 + 50, M = 500, K = 500;
int n, m, q, o[N]; 
vector<int> S; int in[N], nd;
vector<pi> G[N]; int a[M][N];
ll sm[N][2], Ans;
ll query(int x){
	ll as = sm[x][o[x]] - sm[x][o[x]^1];
	ll tmp = 0;
	for(int t : S){
		if(o[t] ^ o[x]) as -= (ll)a[in[t]][x], tmp -= a[in[t]][x];
		else as += (ll)a[in[t]][x], tmp += a[in[t]][x];
	}
	return as;
}
void putin(int x){
	if(in[x]) return;
	if(G[x].size()<=K) return; S.pb(x); in[x]=++nd;
	for(auto v : G[x]) a[in[x]][v.fi] = v.se, sm[v.fi][o[x]] -= v.se;
}
int main(){
	freopen("strength.in","r",stdin);
	freopen("strength.out","w",stdout);
	n=read(), m=read(), q=read();
	for(int i=1; i<=n; i++) o[i]=read();
	for(int i=1,x,y,v; i<=m; i++){
		x=read(), y=read(), v=read();
		G[x].pb(pi(y,v)); G[y].pb(pi(x,v));
		sm[x][o[y]]+=(ll)v;
		sm[y][o[x]]+=(ll)v;
	} for(int i=1; i<=n; i++) Ans+=sm[i][o[i]^1]; Ans>>=1;
	int TIME=0;
	while(q--){
		int op=read();
		if(op==3) cout<<Ans<<'\n';
		if(op==1){
			int x=read(); Ans+=query(x); 
			if(G[x].size()<=K)
			for(auto v : G[x]) sm[v.fi][o[x]]-=v.se, sm[v.fi][o[x]^1]+=v.se;
			else putin(x); o[x]^=1;
		} 
		if(op==2){
			int x=read(), y=read(), v=read();
			putin(x); putin(y); int pr=-1;
			if(in[x]) pr=a[in[x]][y], a[in[x]][y]=v;
			else for(auto &t : G[x]) if(t.fi==y) pr=t.se, t.se=v;
			if(in[y]) pr=a[in[y]][x], a[in[y]][x]=v;
			else for(auto &t : G[y]) if(t.fi==x) pr=t.se, t.se=v;
			if(!in[y]) sm[x][o[y]]+=(ll)v-max(0,pr);
			if(!in[x]) sm[y][o[x]]+=(ll)v-max(0,pr);
			if(o[x]^o[y]) Ans+=(ll)v-max(0,pr);
			if(pr==-1){
				G[x].pb(pi(y,v)), G[y].pb(pi(x,v));
				if(in[x]) a[in[x]][y]=v;
				if(in[y]) a[in[y]][x]=v;
			}
		}
	} return 0;
}
  • BB:注意到每隻青蛙能不能跳出去是獨立的,我們可以令 dpidp_i 表示考慮 wj>iw_j>i 的青蛙,當前可以放上 w=iw=i 的青蛙的最大高度,dpjwi=dpj+hi(j(wi,wi2))dp_{j-w_i}=dp_j+h_i(j\in(w_i,w_i*2)),複雜度 O(wi)O(\sum w_i)
#include<bits/stdc++.h>
#define cs const
using namespace std;
cs int N = 1e5 + 50, M = 1e8 + 5;
struct node{ int l, w, h; };
int dp[M], n, d; node a[N];
int main(){
	#ifdef FSYolanda
	freopen("1.in","r",stdin);
	#endif
	scanf("%d%d",&n,&d);
	for(int i=1; i<=n; i++)
	scanf("%d%d%d",&a[i].l,&a[i].w,&a[i].h);
	sort(a+1,a+n+1,[](cs node &i, cs node &j){ return i.w>j.w; });
	int ans = 0, las = 1e8;
	for(int u=1; u<=n; u++){
		int w=a[u].w; if(a[u].l+dp[w]>d) ++ans;
		for(int i=min((int)1e8-w,w-1); i>=1; i--) 
		dp[i]=max(dp[i],dp[i+w]+a[u].h); 
	} cout<<ans; 
}
  • CC:掃描線 + 單調棧即可,需要維護歷史最大值的和,開始寫了幾發 pushdownpushdown 都掛了,最後抄的仲爺的,即維護 (a,b,c,d)(a,b,c,d) 表示 (sum,ans)=(asum+b,ans+csum+d)(sum,ans)=(a*sum+b,ans+c*sum+d)
#include<bits/stdc++.h>
#define cs const
#define pb push_back
#define fi first
#define se second
using namespace std;
namespace IO{
	cs int Rlen=1<<22|1;
	inline char gc(){
		static char buf[Rlen],*p1,*p2;
		(p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin));
		return p1==p2?EOF:*p1++;
	} int read(){
		int x=0; char c=gc(); bool f=false;
		while(!isdigit(c)) f=c=='-', c=gc();
		while(isdigit(c)) x=(((x<<2)+x)<<1)+(c^48), c=gc();
		return f?-x:x;
	}
} using namespace IO;
typedef long long ll;
typedef pair<int, int> pi;
cs int N = 2e5 + 50;
cs int Mod = 1e9;
cs int INF = 1e9 + 7;
int mul(int a, int b){ return 1ll * a * b % Mod; }
int T, n, a[N];
struct qry{ int l, r, c, op; };
vector<qry> S[N];
ll as[N];
struct coe{
	ll a, b, c, d; 
	coe(ll _a=1, ll _b=0, ll _c=0, ll _d=0){ a=_a; b=_b; c=_c; d=_d; }
	coe operator + (cs coe &A){
		return coe(a*A.a,b*A.a+A.b,a*A.c+c,d+A.d+b*A.c);
	} bool z(){ return a==1&&!b&&!c&&!d; }
};
namespace SGT{
	cs int N = ::N << 2;
	#define mid ((l+r)>>1)
	ll sm[N], as[N], len[N]; coe tag[N];
	void build(int x, int l, int r){
		sm[x]=as[x]=0; tag[x]=coe(); len[x]=r-l+1; if(l==r) return;
		build(x<<1,l,mid); build(x<<1|1,mid+1,r); 
	}
	void pushup(int x){ 
		sm[x]=sm[x<<1]+sm[x<<1|1]; 
		as[x]=as[x<<1]+as[x<<1|1];
	}
	void cov(int x, coe v){ 
		as[x]+=v.c*sm[x]+v.d*len[x];
		sm[x]=v.a*sm[x]+v.b*len[x];
		tag[x]=tag[x]+v;
	}
	void down(int x){ if(!tag[x].z()) cov(x<<1,tag[x]), cov(x<<1|1,tag[x]), tag[x]=coe(); }
	void mdf(int x, int l, int r, int L, int R, coe v){
		if(L<=l&&r<=R) return cov(x,v),void(); down(x);
		if(L<=mid) mdf(x<<1,l,mid,L,R,v);
		if(R>mid) mdf(x<<1|1,mid+1,r,L,R,v); pushup(x);
	} 
	ll query(int x, int l, int r, int L, int R){
		if(L<=l&&r<=R) return as[x]; down(x); ll as=0;
		if(L<=mid) as+=query(x<<1,l,mid,L,R);
		if(R>mid) as+=query(x<<1|1,mid+1,r,L,R); return as;
	}
	void ddd(int x, int l, int r){
		if(l==r) return; down(x);
		ddd(x<<1,l,mid); ddd(x<<1|1,mid+1,r); pushup(x);
	}
}
void work(){
	SGT::build(1,1,n);
	static int sta[N]; int top=0;
	for(int i=1; i<=n; i++){
		while(top&&a[sta[top]]<a[i]) --top;
		SGT::mdf(1,1,n,sta[top]+1,i,{0,a[i],0,0}); sta[++top]=i;
		SGT::cov(1,{1,0,1,0}); for(auto t : S[i])
		as[t.c] += t.op * SGT::query(1,1,n,t.l,t.r);
	}
}
int main(){
	#ifdef FSYolanda
	freopen("sum.in","r",stdin);
//	freopen("sum.out","w",stdout);
	#endif
	T=read();
	for(int i=1,l1,r1,l2,r2; i<=T; i++){
		l1=read(), r1=read(), l2=read(), r2=read();
		if(r2<l1) continue; n=max(n,max(r1,r2));
		S[r2].pb({l1,r1,i,1});
		if(l2>1) S[l2-1].pb({l1,r1,i,-1});
	} for(int i=1,a=1,b=1; i<=n; i++)
		a=mul(a,1023), b=mul(b,1025), ::a[i]=a^b;
	work(); for(int i=1; i<=n; i++) a[i]=-a[i]; work();
	for(int i=1; i<=T; i++) cout<<as[i]<<'\n';
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章