ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2022南外集训 Day2

2022-07-05 20:31:57  阅读:172  来源: 互联网

标签:GCC 2022 int Day2 long 南外 pragma include optimize


杂言

今天分块专场,感觉前几题很基础,就是细节太多
卡常差评

T1 单点修改 区间查询

大力分块 (你只管大力)

T1 accept
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<string> 
#include<cstdlib>
#include<set>
#include<bitset>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=1e5+5;
#define int long long
inline int read()
{
	int x=0,y=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') y=-1; c=getchar();}
	while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	return x*y;
}
int n,val[maxn],m;
char s[10];
int block,bel[maxn];
int sum[maxn];
signed main()
{
	n=read(); m=read();
	for(int i=1;i<=n;i++) val[i]=read();
	block=(int)sqrt(n);
	for(int i=1;i<=n;i++)
		bel[i]=(i-1)/block+1;
	int len=bel[n];
	for(int i=1;i<=len;i++) 
	{
		int l=(i-1)*block+1,r=i*block;
		for(int j=l;j<=r;j++) sum[i]+=val[j];
	}
	while(m--)
	{
		int x,y,ans(0);
		scanf("%s",s+1);
		x=read(); y=read();
		if(s[1]=='Q')
		{
			if(bel[x]==bel[y])
			{
				for(int i=x;i<=y;i++) ans+=val[i];
				printf("%lld\n",ans);
				continue;
			}
			for(int i=x;i<=bel[x]*block;i++) ans+=val[i];
			for(int i=(bel[y]-1)*block+1;i<=y;i++) ans+=val[i];
			for(int i=bel[x]+1;i<=bel[y]-1;i++) ans+=sum[i];
			printf("%lld\n",ans);
		}
		else sum[bel[x]]+=y-val[x],val[x]=y;
	}
	return 0;
}

T2 区间加法 单点查询

没啥可说

T2 accept
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<string> 
#include<cstdlib>
#include<set>
#include<bitset>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=1e5+5;
#define int long long
inline int read()
{
    int x=0,y=1; char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') y=-1; c=getchar();}
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*y;
}
int n,val[maxn],m;
char s[10];
int block,bel[maxn];
int tag[maxn];
signed main()
{
    n=read();
    for(int i=1;i<=n;i++) val[i]=read();
    block=(int)sqrt(n);
    for(int i=1;i<=n;i++)
        bel[i]=(i-1)/block+1;
    while(n--)
    {
        int x,y,ans(0),opt,c;
        opt=read();
        x=read(); y=read(); c=read();
        if(!opt)
        {
            if(bel[x]==bel[y])
            {for(int i=x;i<=y;i++) val[i]+=c; continue;}
            for(int i=x;i<=bel[x]*block;i++) val[i]+=c;
            for(int i=(bel[y]-1)*block+1;i<=y;i++) val[i]+=c;
            for(int i=bel[x]+1;i<=bel[y]-1;i++) tag[i]+=c;
        }
        else printf("%lld\n",val[y]+tag[bel[y]]);
    }
    return 0;
}

T3 区间加法 求x前驱

就是小于x最大的那个,我们直接对每个块里面的东西排序,左右分块可以暴力,中间二分即可

T3 O2 accept
#pragma GCC optimize(2)
 
#define FASTER
#ifdef FASTER
#pragma GCC diagnostic error "-std=c++11"
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#endif
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<string> 
#include<cstdlib>
#include<set>
#include<bitset>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=1e5+5;
const int inf=0x80000000;
#define int long long
inline int read()
{
	int x=0,y=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') y=-1; c=getchar();}
	while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	return x*y;
}
int n,val[maxn];
int block,bel[maxn];
int tag[1005],ans(0);
vector<int> b[1005];
signed main()
{
	n=read();
	for(int i=1;i<=n;i++) val[i]=read();
	block=pow(n,(double)2/(double)3);
	for(int i=1;i<=n;i++)
		bel[i]=(i-1)/block+1,b[bel[i]].push_back(val[i]);
	int len=bel[n];
	for(int i=1;i<=len;i++) 
		sort(b[i].begin(),b[i].end());
	int p=0;
	for(int k=1;k<=n;k++)
	{
		int x,y,opt,c;
		opt=read();
		x=read(); y=read(); c=read();
		if(!opt)
		{
			if(bel[x]==bel[y])
			{
				p=bel[x];
				b[p].clear();
				for(int i=x;i<=y;i++) val[i]+=c;
				for(int i=(bel[x]-1)*block+1;i<=bel[x]*block;i++)
					b[p].push_back(val[i]);
				sort(b[p].begin(),b[p].end());
				continue;
			}
			p=bel[x];
			for(int i=x;i<=bel[x]*block;i++) val[i]+=c;
			b[p].clear();
			for(int i=(bel[x]-1)*block+1;i<=bel[x]*block;i++)
				b[p].push_back(val[i]);
			sort(b[p].begin(),b[p].end());
			p=bel[y];
			for(int i=(bel[y]-1)*block+1;i<=y;i++) val[i]+=c;
			b[p].clear();
			for(int i=(bel[y]-1)*block+1;i<=min(n,bel[y]*block);i++)
				b[p].push_back(val[i]);
			sort(b[p].begin(),b[p].end());
			for(int i=bel[x]+1;i<=bel[y]-1;i++) tag[i]+=c;
		}
		else
		{
			ans=-1;
			if(bel[x]==bel[y])
			{
				for(int i=x;i<=y;i++)
					if(val[i]+tag[bel[x]]<c) ans=max(ans,val[i]+tag[bel[x]]);
				printf("%lld\n",ans); continue;
			}
			for(int i=x;i<=bel[x]*block;i++)
				if(val[i]+tag[bel[i]]<c) ans=max(ans,val[i]+tag[bel[i]]);
			for(int i=(bel[y]-1)*block+1;i<=y;i++)
				if(val[i]+tag[bel[i]]<c) ans=max(ans,val[i]+tag[bel[i]]);
			for(int i=bel[x]+1;i<=bel[y]-1;i++)
			{
				int tmp=lower_bound(b[i].begin(),b[i].end(),c-tag[i])-b[i].begin();
				if(tmp) ans=max(ans,b[i][tmp-1]+tag[i]);
			}
			printf("%lld\n",ans);
		}
	}
	return 0;
}

T4 区间加法 询问区间内小于x的个数

跟上面一样,也需要二分位置

T4 O2 accept
#pragma GCC optimize(2)
 
#define FASTER
#ifdef FASTER
#pragma GCC diagnostic error "-std=c++11"
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#endif
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<string> 
#include<cstdlib>
#include<set>
#include<bitset>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=5e4+5;
const int inf=0x80000000;
#define int long long
inline int read()
{
	int x=0,y=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') y=-1; c=getchar();}
	while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	return x*y;
}
int n,val[maxn];
int block,bel[maxn];
int tag[1005],ans(0);
vector<int> b[1005];
signed main()
{
	n=read();
	for(int i=1;i<=n;i++) val[i]=read();
	block=sqrt(n);
	for(int i=1;i<=n;i++)
		bel[i]=(i-1)/block+1,b[bel[i]].push_back(val[i]);
	int len=bel[n];
	for(int i=1;i<=len;i++) 
		sort(b[i].begin(),b[i].end());
	int p=0;
	for(int k=1;k<=n;k++)
	{
		int x,y,opt,c;
		opt=read();
		x=read(); y=read(); c=read();
		if(!opt)
		{
			if(bel[x]==bel[y])
			{
				p=bel[x];
				b[p].clear();
				for(int i=x;i<=y;i++) val[i]+=c;
				for(int i=(bel[x]-1)*block+1;i<=bel[x]*block;i++)
					b[p].push_back(val[i]);
				sort(b[p].begin(),b[p].end());
				continue;
			}
			p=bel[x];
			for(int i=x;i<=bel[x]*block;i++) val[i]+=c;
			b[p].clear();
			for(int i=(bel[x]-1)*block+1;i<=bel[x]*block;i++)
				b[p].push_back(val[i]);
			sort(b[p].begin(),b[p].end());
			p=bel[y];
			for(int i=(bel[y]-1)*block+1;i<=y;i++) val[i]+=c;
			b[p].clear();
			for(int i=(bel[y]-1)*block+1;i<=min(n,bel[y]*block);i++)
				b[p].push_back(val[i]);
			sort(b[p].begin(),b[p].end());
			for(int i=bel[x]+1;i<=bel[y]-1;i++) tag[i]+=c;
		}
		else
		{
			ans=0;
			if(bel[x]==bel[y])
			{
				for(int i=x;i<=y;i++)
					if(val[i]+tag[bel[x]]<c*c) ans++;
				printf("%lld\n",ans); continue;
			}
			for(int i=x;i<=bel[x]*block;i++)
				if(val[i]+tag[bel[i]]<c*c) ans++;
			for(int i=(bel[y]-1)*block+1;i<=y;i++)
				if(val[i]+tag[bel[i]]<c*c) ans++;
			for(int i=bel[x]+1;i<=bel[y]-1;i++)
			{
				int tmp=lower_bound(b[i].begin(),b[i].end(),c*c-tag[i])-b[i].begin();
				ans+=tmp;
			}
			printf("%lld\n",ans);
		}
	}
	return 0;
}

T5 区间修改 区间查询

这个处理的问题就是需要考虑每次不整的块对当前块\(sum\)值的影响

T5 accept
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<string> 
#include<cstdlib>
#include<set>
#include<bitset>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=5e4+5;
#define int long long
inline int read()
{
	int x=0,y=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') y=-1; c=getchar();}
	while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	return x*y;
}
int n,val[maxn];
int block,bel[maxn];
int sum[maxn],tag[maxn];
signed main()
{
	n=read();
	for(int i=1;i<=n;i++) val[i]=read();
	block=(ll)sqrt(n);
	for(int i=1;i<=n;i++)
		bel[i]=(i-1)/block+1;
	int len=bel[n];
	for(int i=1;i<=len;i++) 
	{
		tag[i]=0;
		int l=(i-1)*block+1,r=i*block;
		for(int j=l;j<=r;j++) sum[i]+=val[j];
	}
	for(int k=1;k<=n;k++)
	{
		int x,y,ans=0,opt,c;
		opt=read();
		x=read(); y=read(); c=read();
		if(x>y) swap(x,y);
		if(!opt)
		{
			if(bel[x]==bel[y])
			{
				for(int i=x;i<=y;i++) val[i]+=c;
				sum[bel[x]]+=(y-x+1)*c;
				continue;
			}
			for(int i=x;i<=bel[x]*block;i++) val[i]+=c;
			sum[bel[x]]+=(bel[x]*block-x+1)*c;
			for(int i=(bel[y]-1)*block+1;i<=y;i++) val[i]+=c;
			sum[bel[y]]+=(y-(bel[y]-1)*block)*c;
			for(int i=bel[x]+1;i<=bel[y]-1;i++)
				tag[i]+=c,sum[i]+=block*c;
		}
		else
		{
			if(bel[x]==bel[y])
			{for(int i=x;i<=y;i++) ans=(ans+val[i]+tag[bel[i]])%(c+1); 
			printf("%lld\n",ans%(c+1)); continue;}
			for(int i=x;i<=bel[x]*block;i++) ans=(ans+tag[bel[i]]+val[i])%(c+1);
			for(int i=(bel[y]-1)*block+1;i<=y;i++) ans=(ans+tag[bel[i]]+val[i])%(c+1);
			for(int i=bel[x]+1;i<=bel[y]-1;i++) ans=(ans+sum[i])%(c+1);
			printf("%lld\n",ans%(c+1));
		}
	}
	return 0;
}
/*4
1 1 1 1
0 1 3 2
0 2 3 1
0 3 4 9
1 1 4 10*/

T6 区间开方 区间求和

和线段树那里写的一样,int开方只会开最多5次
5次 \(O(n\cdot log n)\)

T6 segtree accept
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<string> 
#include<cstdlib>
#include<set>
#include<bitset>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=1e5+5;
#define lc(x) x<<1
#define rc(x) x<<1|1
#define mx(x) tree[x].mx
#define int long long
inline int read()
{
	int x=0,y=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') y=-1; c=getchar();}
	while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	return x*y;
}
int n,a[maxn],m;
struct node
{
	ll sum,mx;
}tree[maxn<<2];
void push_up(int id)
{
	tree[id].sum=tree[lc(id)].sum+tree[rc(id)].sum;
	mx(id)=max(mx(lc(id)),mx(rc(id)));
	return ;
}
void build(int id,int l,int r)
{
	if(l==r)
	{tree[id].mx=tree[id].sum=a[l]; return ;}
	int mid=(l+r)>>1;
	build(id<<1,l,mid);
	build(id<<1|1,mid+1,r);
	push_up(id);
	return ;
}
void modify(int id,int l,int r,int x,int y)
{
	if(mx(id)==1||mx(id)==0) return ;
	if(l==r)
	{
		tree[id].sum=(ll)floor(sqrt(tree[id].mx));
		tree[id].mx=tree[id].sum;
		return ;
	}
	int mid=(l+r)>>1;
	if(x<=mid) modify(lc(id),l,mid,x,y);
	if(y>mid) modify(rc(id),mid+1,r,x,y);
	push_up(id);
	return ;
}
int query(int id,int l,int r,int x,int y)
{
	if(x<=l&&r<=y) return tree[id].sum;
	int mid=(l+r)>>1;
	ll ans=0;
	if(x<=mid) ans+=query(lc(id),l,mid,x,y);
	if(y>mid) ans+=query(rc(id),mid+1,r,x,y);
	return ans;
}
signed main()
{
	n=read();
	for(int i=1;i<=n;i++) a[i]=read();
	build(1,1,n);
	for(int p=1;p<=n;p++)
	{
		int x,l,r,c;
		x=read(); l=read(); r=read(); c=read();
		if(x==0) modify(1,1,n,l,r);
		else printf("%lld\n",query(1,1,n,l,r));
	}
	return 0;
} 

T7

T8 区间乘法加法 单点查询

和线段树思路一样,优先考虑乘法,再考虑加法

T8 accept
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<string> 
#include<cstdlib>
#include<set>
#include<bitset>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=1e6+5;
const int inf=0x80000000;
const int mod=1e4+7;
#define int long long
inline int read()
{
	int x=0,y=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') y=-1; c=getchar();}
	while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	return x*y;
}
int n,val[maxn];
int block,bel[maxn];
int tag[1005],mul[1005],ans(0);
signed main()
{
	n=read();
	for(int i=1;i<=n;i++) val[i]=read()%mod;
	block=sqrt(n);
	for(int i=1;i<=n;i++)
		bel[i]=(i-1)/block+1; 
	int len=bel[n];
	for(int i=1;i<=len;i++) mul[i]=1;
	for(int k=1;k<=n;k++)
	{
		int x,y,opt,c;
		opt=read();
		x=read(); y=read(); c=read();
		if(opt==0)
		{
			if(bel[x]==bel[y])
			{
				for(int i=(bel[x]-1)*block+1;i<=bel[x]*block;i++)
					val[i]=(val[i]*mul[bel[x]])%mod,val[i]=(val[i]+tag[bel[x]])%mod;
				for(int i=x;i<=y;i++) val[i]=(val[i]+c)%mod;
				tag[bel[x]]=0; mul[bel[x]]=1;
				continue;
			}
			for(int i=(bel[x]-1)*block+1;i<=bel[x]*block;i++)
				val[i]=(val[i]*mul[bel[x]])%mod,val[i]=(val[i]+tag[bel[x]])%mod;
			for(int i=x;i<=bel[x]*block;i++) val[i]=(val[i]+c)%mod;
			tag[bel[x]]=0; mul[bel[x]]=1;
			for(int i=(bel[y]-1)*block+1;i<=bel[y]*block;i++)
				val[i]=(val[i]*mul[bel[y]])%mod,val[i]=(val[i]+tag[bel[y]])%mod;
			for(int i=(bel[y]-1)*block+1;i<=y;i++) val[i]=(val[i]+c)%mod;
			tag[bel[y]]=0; mul[bel[y]]=1;
			for(int i=bel[x]+1;i<=bel[y]-1;i++) tag[i]=(tag[i]+c)%mod;
		}
		else if(opt==1)
		{
			if(bel[x]==bel[y])
			{
				for(int i=(bel[x]-1)*block+1;i<=bel[x]*block;i++)
					val[i]=(val[i]*mul[bel[x]])%mod,val[i]=(val[i]+tag[bel[x]])%mod;
				for(int i=x;i<=y;i++) val[i]=(val[i]*c)%mod;
				tag[bel[x]]=0; mul[bel[x]]=1;
				continue;
			}
			for(int i=(bel[x]-1)*block+1;i<=bel[x]*block;i++)
				val[i]=(val[i]*mul[bel[x]])%mod,val[i]=(val[i]+tag[bel[x]])%mod;
			for(int i=x;i<=bel[x]*block;i++) val[i]=(val[i]*c)%mod;
			tag[bel[x]]=0; mul[bel[x]]=1;
			for(int i=(bel[y]-1)*block+1;i<=bel[y]*block;i++)
				val[i]=(val[i]*mul[bel[y]])%mod,val[i]=(val[i]+tag[bel[y]])%mod;
			for(int i=(bel[y]-1)*block+1;i<=y;i++) val[i]=(val[i]*c)%mod;
			tag[bel[y]]=0; mul[bel[y]]=1;
			for(int i=bel[x]+1;i<=bel[y]-1;i++) mul[i]=(mul[i]*c)%mod,tag[i]=(tag[i]*c)%mod;
		}
		else printf("%lld\n",(val[y]*mul[bel[y]]%mod+tag[bel[y]])%mod);
	}
	return 0;
}

T9

T10 区间最小众数

原题链接:Luogu P4168 [Violet]蒲公英
原题强制在线,其实强不强制都一样
因为是众数,没法主席树,考虑大力分块
每次我们需要维护一个东西,就是区间内整块中的众数以及其出现次数
考虑小dp
预处理出两个数组:
\(p[i][j]\):表示第\(i\)个块 到第\(j\)个块的(最小的)众数。
\(s[i][j]\):类似于前缀和,在前\(i\)个(包括 \(i\) )个块中\(j\)(离散化之后的值)出现了几次
考虑怎么处理,\(s\)数组我们每一次先继承\(s[i-1][j]\),然后在当前块\(i\)中直接扫
复杂度是:\(O(n \sqrt n)\)
而\(p[i][j]\),我们可以枚举\(i,j\)块,然后枚举块\(j\),我们知道\(p[i][j-1]\),那么就可以利用它去更新\(p[i][j]\)
复杂度是:\(O(\sqrt n \cdot \sqrt n \cdot \sqrt n)=O(n \sqrt n)\)
那么,处理完这些,我们可以对于不整的块(左端和右端),进行暴力
细节很多,还得仔细

T10 accept
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<string> 
#include<cstdlib>
#include<set>
#include<bitset>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=1e5+5;
const int maxm=355;
inline int read()
{
	int x=0,y=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') y=-1; c=getchar();}
	while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	return x*y;
}
int block,n,m;
int b[maxn],col[maxn];
int len(0),cnt(0);
int get(int pos) {return (pos-1)/block+1;}
int sum[maxm][maxn];
int f[maxm][maxm],t[maxn];
int main()
{
	n=read();
	block=(int)sqrt(n);
	for(int i=1;i<=n;i++) b[i]=col[i]=read();
	sort(b+1,b+1+n);
	len=unique(b+1,b+1+n)-b-1;
	cnt=(n-1)/block+1;
	for(int i=1;i<=n;i++)
		col[i]=lower_bound(b+1,b+1+len,col[i])-b;
	for(int i=1;i<=cnt;i++)
	{
		for(int j=block*(i-1)+1;j<=min(block*i,n);j++)
			sum[i][col[j]]++;
		for(int j=1;j<=len;j++)
			sum[i][j]+=sum[i-1][j];
	}
	for(int i=1;i<=cnt;i++)
	{
		for(int j=i;j<=cnt;j++)
		{
			int mx=f[i][j-1];
			for(int k=block*(j-1);k<=min(block*j,n);k++)
				if(sum[j][col[k]]-sum[i-1][col[k]]>sum[j][mx]-sum[i-1][mx]||(
				(sum[j][col[k]]-sum[i-1][col[k]]==sum[j][mx]-sum[i-1][mx])&&col[k]<mx))
				mx=col[k];
			f[i][j]=mx;
		}
	}
	for(int ppp=1;ppp<=n;ppp++)
	{
		int l=read(),r=read();
		int bl=get(l),br=get(r),mx=0;
		if(br-bl<=1)
		{
			for(int i=l;i<=r;i++) t[col[i]]++;
			for(int i=l;i<=r;i++)
				if(t[col[i]]>t[mx]||(t[col[i]]==t[mx]&&col[i]<mx))
					mx=col[i];
			for(int i=l;i<=r;i++) t[col[i]]=0;
			printf("%d\n",b[mx]);
			continue;
		}
		for(int i=l;i<=block*bl;i++) t[col[i]]++;
		for(int i=block*(br-1)+1;i<=r;i++) t[col[i]]++;
		mx=f[bl+1][br-1];
		for(int i=l;i<=block*bl;i++)
		{
			int pre=t[mx]+sum[br-1][mx]-sum[bl][mx];
			int u=	t[col[i]]+sum[br-1][col[i]]-sum[bl][col[i]];
			if(u>pre||(u==pre&&mx>col[i])) mx=col[i];
		}
		for(int i=block*(br-1)+1;i<=r;i++)
		{
			int pre=t[mx]+sum[br-1][mx]-sum[bl][mx];
			int u=t[col[i]]+sum[br-1][col[i]]-sum[bl][col[i]];
			if(u>pre||(u==pre&&mx>col[i])) mx=col[i];
		}
		for(int i=l;i<=block*bl;i++) t[col[i]]=0;
		for(int i=block*(br-1)+1;i<=r;i++) t[col[i]]=0;
		printf("%d\n",b[mx]);
	}
	return 0;
}

标签:GCC,2022,int,Day2,long,南外,pragma,include,optimize
来源: https://www.cnblogs.com/mastey/p/16448514.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有