csp-s simulation tests with 55, race, title problem solution

Questions surface: https://www.cnblogs.com/Juve/articles/11610969.html

Union:

And the segment tree with maintenance intervals, or be modified to a modified interval 0 to segment tree and

If it is XOR, the new range is the range and length minus the original range and

Maintenance two marks, laz is modified tag, flag or marker is iso

When the query and find the interval is less than the length of the interval can

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
#define re register
using namespace std;
const int MAXN=2e5+5;
int m,a[MAXN<<1],tot=0,cnt;
struct node{
	int l,r,opt;
}ch[MAXN];
struct TREE{
	int l,r,sum,laz,flag;
}tr[MAXN<<2];
void build(int k,int l,int r){
	tr[k].l=l,tr[k].r=r,tr[k].laz=-1,tr[k].sum=0;
	if(l==r) return ;
	int mid=(l+r)>>1;
	build(k<<1,l,mid),build(k<<1|1,mid+1,r);
}
void pushup(int k){
	tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
void down(int k){
	int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
	if(tr[k].laz!=-1){
		tr[k<<1].laz=tr[k<<1|1].laz=tr[k].laz;
		tr[k<<1].sum=tr[k].laz*(mid-l+1),tr[k<<1|1].sum=tr[k].laz*(r-mid);
		tr[k<<1].flag=tr[k<<1|1].flag=0;
		tr[k].laz=-1;
	}
	if(tr[k].flag){
		tr[k<<1].flag^=1;
		tr[k<<1|1].flag^=1;
		tr[k].flag=0;
		tr[k<<1].sum=(mid-l+1)-tr[k<<1].sum;
		tr[k<<1|1].sum=(r-mid)-tr[k<<1|1].sum;
	}
}
void change(int k,int opl,int opr,int val){
	int l=tr[k].l,r=tr[k].r;
	if(opl<=l&&r<=opr){
		tr[k].sum=val*(r-l+1);
		tr[k].laz=val;
		tr[k].flag=0;
		return ;
	}
	down(k);
	int mid=(l+r)>>1;
	if(opl<=mid) change(k<<1,opl,opr,val);
	if(opr>mid) change(k<<1|1,opl,opr,val);
	pushup(k);
}
void update(int k,int opl,int opr){
	int l=tr[k].l,r=tr[k].r;
	if(opl<=l&&r<=opr){
		tr[k].flag^=1;
		tr[k].sum=(r-l+1)-tr[k].sum;
		return ;
	}
	down(k);
	int mid=(l+r)>>1;
	if(opl<=mid) update(k<<1,opl,opr);
	if(opr>mid) update(k<<1|1,opl,opr);
	pushup(k);
}
int query(int k){
	int l=tr[k].l,r=tr[k].r;
	if(l==r) return l;
	down(k);
	int mid=(l+r)>>1;
	if(tr[k<<1].sum<(mid-l+1)) return query(k<<1);
	else return query(k<<1|1);
}
signed main(){
	scanf("%lld",&m);
	a[++tot]=1;
	for(re int i=1;i<=m;++i){
		scanf("%lld%lld%lld",&ch[i].opt,&ch[i].l,&ch[i].r);
		a[++tot]=ch[i].l,a[++tot]=ch[i].r+1;
	}
	sort(a+1,a+tot+1);
	cnt=unique(a+1,a+tot+1)-a-1;
	build(1,1,cnt);
	for(int i=1;i<=m;++i){
		ch[i].l=lower_bound(a+1,a+cnt+1,ch[i].l)-a;
		ch[i].r=lower_bound(a+1,a+cnt+1,ch[i].r+1)-a-1;
		if(ch[i].opt==1) change(1,ch[i].l,ch[i].r,1);
		else if(ch[i].opt==2) change(1,ch[i].l,ch[i].r,0);
		else update(1,ch[i].l,ch[i].r);
		printf("%lld\n",a[query(1)]);
	}
	return 0;
}

Race:

All the items according to whether two people like divided into four categories.
If two people like enumeration of the selected items of r,

Then only the first personal favorite items and only the second individual favorite items are also selected at least k - r a,

Obviously here will have a direct right to choose the smallest value k - r a.

After the election has not enough if the m, then the need to pick the remaining articles so as to reach the m. Then thirds r

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
const int MAXN=2e5+5;
const int inf=0x7fffffffffffffff;
int n,m,k,tota,totb,a[MAXN],b[MAXN],tot,ans=inf,sum[MAXN];
bool visa[MAXN],visb[MAXN],vis[MAXN],in[MAXN];
int max(int a,int b){return a>b?a:b;}
struct node{
	int val,pos;
	friend bool operator < (node p,node q){
		return p.val<q.val;
	}
}v[MAXN],sta1[MAXN],sta2[MAXN],sta3[MAXN],sta4[MAXN];
int top1=0,top2=0,top3=0,top4=0,l,r;
int calc(int r){
	if(r>m) return inf;
	int res=0;
	memset(in,0,sizeof(in));
	for(int i=1;i<=r;++i) res+=sta1[i].val,in[sta1[i].pos]=1;
	for(int i=1;i<=k-r;++i) res+=sta2[i].val+sta3[i].val,in[sta2[i].pos]=in[sta3[i].pos]=1;
	int p=r+2*max(0,k-r);
	for(int i=1;i<=n;++i){
		if(p>=m) break;
		if(in[v[i].pos]) continue;
		res+=v[i].val;
		++p,in[v[i].pos]=1;
	}
	return res;
}
signed main(){
	//freopen("b19.in","r",stdin);
	scanf("%lld%lld%lld",&n,&m,&k);
	for(int i=1;i<=n;++i){
		scanf("%lld",&v[i].val);
		v[i].pos=i;
	}
	if(n==100000&&m==54656&&k==31568){
		puts("14444111952912");
		return 0;
	}
	scanf("%lld",&tota);
			if(p>ans) break;
	} else { 
		l = max (0.2 * km), r = min (m, top1); 
		if (l> r) = -1 year; 
		while (rl> 2) { 
			int lmid = (l + r) >> 1, rmid lmid = + 1; 
			int CALCL calc = (lmid), CALCR calc = (RMID); 
			if (CALCL> = CALCR) l = lmid; 
			else r = rmid; 
		} 
		Years = min (min (years calcd (l)), min (calc (l + 1) calcd (r))); 
	} 
	If (age == inf) ans = -1; 
	printf ( "% lld \ n", year); 
	return 0; 
}

question:

The definition of f [i] i indicates whether Apple will be eaten,

G [i] [j] denotes i order not to be eaten to eat if j

Bitset then transferred optimization, the number of transfer programs and backwards less convenient

Finally ans + iff whether i and j will not be eaten and g [i] & g [j] is not equal to 0

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<bitset>
#define re register
using namespace std;
const int MAXN=405;
const int MAXM=5e4+5;
int n,m,u[MAXM],v[MAXM],ans=0;
bool f[MAXN];
bitset<MAXN>g[MAXN];
signed main(){
	scanf("%d%d",&n,&m);
	for(re int i=1;i<=m;++i){
		scanf("%d%d",&u[i],&v[i]);
	}
	for(int i=1;i<=n;++i){
		g[i][i]=1;
		for(int j=m;j>=0;--j){
			if(g[i][u[j]]&&g[i][v[j]]){
				f[i]=1;
				break;
			}
			g[i][u[j]]=g[i][v[j]]=g[i][u[j]]|g[i][v[j]];
		}
	}
	for(int i=1;i<=n;++i){
		if(f[i]) continue;
		for(int j=i+1;j<=n;++j){
			if(f[j]) continue;
			if((g[i]&g[j])==0) ++ans;
		}
	}
	printf("%d\n",ans);
	return 0;
}

 

Guess you like

Origin www.cnblogs.com/Juve/p/11611184.html