ICode9

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

noip96

2021-11-13 07:00:21  阅读:112  来源: 互联网

标签:int noip96 re freopen using include define


T1

多测不清空,爆零两行泪。

考场想法过于sb,树上带修莫队+查询区间 \(\min/\max\) ,然后就不会了。

结果写的暴力多测没清空,爆零了....改了之后竟然能切?

判断排列直接写个hash就行了...

T2

考场以为是可追溯化并查集之前颓游记的时候发现的,然而并不会,想了想,发现可以用个栈存下操作,然后就不知道该怎么处理了,打了60pts就跑路了。

竟然是套路题

有个东西叫线段树分治,就是维护每个操作能产生影响的区间,统计答案dfs一遍,回溯时撤销当前操作影响。

把每一个操作插入到其能产生影响的区间中,然后用个可撤销并查集维护 \(size\) 大小。

可撤销并查集,就是用个栈存下操作,不能用路径压缩,不然会出错,要用启发式合并来保证复杂度。

Code
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#include<algorithm>
using std::sort;
using std::pair;
using std::vector;
using std::upper_bound;
#define fi first
#define se second
using std::make_pair;
#define pack make_pair
#define push emplace_back
typedef pair<int,int> my;
#define re register
const int MAX = 1e5+3;
const int mod = 1e9+7;
#define long long long
#define scanf oma=scanf
#define freopen file=freopen
int oma;
FILE* file;
namespace some
{
	struct stream
	{
		template<typename type>inline stream &operator >>(type &s)
		{
			bool w=0; s=0; char ch=getchar();
			while(!isdigit(ch)){ w|=ch=='-'; ch=getchar(); }
			while(isdigit(ch)){ s=(s<<1)+(s<<3)+(ch^48); ch=getchar(); }
			return s=w?-s:s,*this;
		}
	}cin;
	int n,m;
	long inv[MAX],ans=1;
	struct data
	{ int op,u,v; }q[MAX];
	vector<pair<my,int>>s;
	#define debug(s) printf("%s\n",s)
}using namespace some;
namespace Data_Structures
{
	auto swap = [](int &a,int &b) { int t=a; a=b,b=t; };
	struct DSU
	{
		int top;
		my sta[MAX];
		int fa[MAX],size[MAX];
		void init()
		{ for(re int i=1; i<=n; i++) { size[fa[i] = i] = 1; } }
		int find(int x)
		{ return x!=fa[x]?find(fa[x]):fa[x]; }
		void merge(int x,int y)
		{
			x = find(x),y = find(y);
			if(x!=y)
			{
				if(size[x]<size[y])
				{ swap(x,y); }
				fa[y] = x,ans = ans*inv[size[x]]%mod*inv[size[y]]%mod*(size[x] += size[y])%mod;
			}
			sta[++top] = pack(x,y);
		}
		void revoke(int cnt)
		{
			int x,y; my now;
			//debug("<---->");
			while(cnt)
			{
				cnt--;
				now = sta[top--],x = now.fi,y = now.se;
				if(x==y)
				{ continue ; }
				//printf("x=%d y=%d sizex=%d sizey=%d\n",x,y ,size[x],size[y]);
				ans = ans*inv[size[x]]%mod*(size[x] -= size[y])%mod*size[fa[y] = y]%mod;
			}
			//debug(">----<");
		}
	}ds;
	struct Segment_Tree
	{
		vector<my>val[MAX<<2];
		#define ls(p) p<<1
		#define rs(p) p<<1|1
		#define mid (l+r>>1)
		void insert(int p,int l,int r,int lp,int rp,my w)
		{
			if(lp<=l&&r<=rp)
			{ val[p].push(w); return ; }
			if(lp<=mid)
			{ insert(ls(p),l,mid,lp,rp,w); }
			if(rp>mid)
			{ insert(rs(p),mid+1,r,lp,rp,w); }
		}
		void dfs(int p,int l,int r)
		{
			for(auto x : val[p])
			{ ds.merge(x.fi,x.se); }
			if(l==r)
			{ printf("%lld\n",ans); goto jump; }
			dfs(ls(p),l,mid),dfs(rs(p),mid+1,r);
			jump: ;
			/*printf("l=%d r=%d\n",l,r);*/ ds.revoke(val[p].size());
		}
	}Tree;
}using namespace Data_Structures;
namespace OMA
{
	auto main = []() -> signed
	{
		//#define local
		#ifdef local
		debug("look here! if you want submit,please closed this");
		freopen("node.in","r",stdin); freopen("my.out","w",stdout);
		#endif
		freopen("b.in","r",stdin); freopen("b.out","w",stdout);
		cin >> n >> m; inv[1] = 1;
		for(re int i=1; i<=m; i++)
		{
			cin >> q[i].op >> q[i].u >> q[i].v;
			if(q[i].u>q[i].v)
			{ swap(q[i].u,q[i].v); }
			if(q[i].op==2)
			{ s.push(pack(pack(q[i].u,q[i].v),i)); }
		}
		sort(s.begin(),s.end());
		for(re int i=1; i<=m; i++)
		{
			if(q[i].op==1)
			{
				int r;
				int pos = upper_bound(s.begin(),s.end(),pack(pack(q[i].u,q[i].v),i))-s.begin();
				if(pos==s.size())
				{ Tree.insert(1,1,m,i,m,pack(q[i].u,q[i].v)); continue ; }
				pair<my,int> p = s[pos];
				if(p.fi!=pack(q[i].u,q[i].v))
				{ Tree.insert(1,1,m,i,m,pack(q[i].u,q[i].v)); /*r = m;*/ }
				else
				{ Tree.insert(1,1,m,i,p.se-1,pack(q[i].u,q[i].v)); /*r = p.se-1; printf("%d %d\n",i,p.se);*/ }
				//printf("l=%d r=%d\n",i,r);
			}
		}
		for(re int i=2; i<=n; i++)
		{ inv[i] = (mod-mod/i)*inv[mod%i]%mod; }
		ds.init(); Tree.dfs(1,1,m);
		return 0;
	};
};
signed main()
{ return OMA::main(); }

T3

考场啥也不会,cdq也没写出来...

先考虑一个这样一个问题,给定三个排列 \(a,b,c\) ,求满足 \(a_{i}<a_{j},b_{i}<b_{j},c_{i}<c_{j}\) 的 \((i,j)\) 个数,其中 \(a\) 序列为下标序列,直接写cdq肯定不行。

用题解做法 对 \((a,b),(a,c),(b,c)\) 这三对分别求一遍二维偏序,那么每一对 \((i,j)\) 不是满足二维偏序,就是满足三维偏序,因为 \(a\) 序列为下标,肯定满足 \(i<j\) , \(b_{i},b_{j}\) 之间的关系只有大于小于, \(c_{i},c_{j}\) 同理,俩都大于交换一下就行。

那么这样在统计给这三对二维偏序求和时,如果 \((i,j)\) 满足的是三维偏序关系,会被算三遍,否则只会算一遍。

设二维偏序之和为 \(m\) , 所以三维偏序的数量就是 \(\frac{m-\tbinom{n}{2}}{2}\) 。

这是没有-1的情况,有-1的情况,则预处理出从 \(q\) 没有的数中选,比 \(i\) 大的概率,用树状数组维护的时候插概率就行了,如果都是-1,那么概率就是 \(\frac{1}{2}\) 。因为贡献是1,所以期望就是概率。

不过战神的容斥做法更好搞一些,也更好理解。

Code
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#include<algorithm>
using std::sort;
using std::vector;
#define re register
#define pack push_back
const int MAX = 1e6+3;
#define long long long
#define scanf oma=scanf
const int mod = 998244353;
const int inv2 = 499122177;
#define freopen file=freopen
int oma;
FILE* file;
namespace some
{
	struct stream
	{
		template<typename type>inline stream &operator >>(type &s)
		{
			bool w=0; s=0; char ch=getchar();
			while(!isdigit(ch)){ w|=ch=='-'; ch=getchar(); }
			while(isdigit(ch)){ s=(s<<1)+(s<<3)+(ch^48); ch=getchar(); }
			return s=w?-s:s,*this;
		}
	}cin;
	long res;
	long rec[MAX];
	bool tub[MAX];
	int seq[MAX],tot;
	int n,p[MAX],q[MAX];
	auto quickpow = [](int a,int b,int res = 1)
	{
		while(b)
		{
			if(b&1)
			{ res = 1ll*res*a%mod; }
			a = 1ll*a*a%mod,b >>= 1;
		}
		return res;
	};
	#define debug(s) printf("%s\n",s)
}using namespace some;
namespace Data_Structures
{
	struct BIT
	{
		int val[MAX];
		#define lowbit(x) x&-x
		void clear()
		{ memset(val,0,sizeof(int)*(n+1)); }
		void modify(int x,int w)
		{ for(re int i=x; i<=n; i+=lowbit(i)) { (val[i] += w) %= mod; } }
		int query(int x,int res = 0)
		{ for(re int i=x; i; i-=lowbit(i)) { (res += val[i]) %= mod; } return res; }
	}Tree;
}using namespace Data_Structures;
namespace OMA
{
	auto main = []() -> signed
	{
		//#define local
		#ifdef local
		debug("look here! if you want submit,please closed this");
		freopen("node.in","r",stdin); freopen("my.out","w",stdout);
		#endif
		freopen("c.in","r",stdin); freopen("c.out","w",stdout);
		cin >> n;
		for(re int i=1; i<=n; i++)
		{ cin >> p[i]; }
		for(re int i=1; i<=n; i++)
		{ cin >> q[i]; if(q[i]!=-1) { seq[++tot] = i; tub[q[i]] = true; } }
		for(re int i=1; i<=tot; i++)
		{ (res += Tree.query(p[seq[i]])) %= mod; Tree.modify(p[seq[i]],1); }
		Tree.clear();
		for(re int i=1; i<=tot; i++)
		{ (res += Tree.query(q[seq[i]])) %= mod; Tree.modify(q[seq[i]],1); }
		Tree.clear(); sort(seq+1,seq+1+tot,[](const int &x,const int &y) { return q[x]<q[y]; });
		for(re int i=1; i<=tot; i++)
		{ (res += Tree.query(p[seq[i]])) %= mod; Tree.modify(p[seq[i]],1); }
		//printf("res=%lld\n",res);
		res = (res-1ll*tot*(tot-1)%mod*inv2%mod+mod)%mod*inv2%mod,tot = 0;
		//printf("res=%lld\n",res);
		for(re int i=1; i<=n; i++)
		{
			if(!tub[i])
			{ seq[++tot] = i; /*printf("i=%d ",i);*/ }
		}
		//printf("\ntot=%d\n",tot);
		long inv = quickpow(tot,mod-2);
		for(re int i=1,pos=1; i<=n; i++)
		{
			while(pos<=tot&&seq[pos]<=i)
			{ pos++; }
			//printf("%d\n",pos);
			rec[i] = (tot-pos+1)*inv%mod;
			//printf("rec[%d]=%lld\n",i,rec[i]);
		}
		Tree.clear();
		for(re int i=1; i<=n; i++)
		{
			if(q[i]!=-1)
			{ Tree.modify(p[i],rec[q[i]]); }
			else
			{ (res += Tree.query(p[i])) %= mod; }
		}
		Tree.clear();
		for(re int i=n; i; i--)
		{
			if(q[i]!=-1)
			{ Tree.modify(p[i],mod+1-rec[q[i]]); }
			else
			{ (res += Tree.query(n)-Tree.query(p[i])+mod) %= mod; }
		}
		Tree.clear();
		for(re int i=1; i<=n; i++)
		{ if(q[i]==-1) { (res += Tree.query(p[i])) %= mod; Tree.modify(p[i],inv2); } }
		printf("%lld\n",res);
		return 0;
	};
};
signed main()
{ return OMA::main(); }

T4

不会,咕...

image

标签:int,noip96,re,freopen,using,include,define
来源: https://www.cnblogs.com/-OMA-/p/15547201.html

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

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

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

ICode9版权所有