ICode9

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

[考试总结]noip模拟77

2021-10-17 09:01:58  阅读:125  来源: 互联网

标签:std try ch noip int register 77 模拟 define


话说开始下午考试了,然后改题飞快还不是因为数据太水了所以这一次就不咕了。

最大或

这个题目还是比较玄学的。

首先可以发现在两个二进制数的位数不相同的时候,那么答案就一定是所有都是 \(1\) 的长度为 \(r\) 的位数的二进制。

那么位数相同的时候该怎么办呢?

然后开始猜结论

因为暴力过于好写,所以猜一个结论就对拍一次。

然后发现如果在两个数的第一个不相同的位那里后面全部设置成 \(1\) 就不会错误了。

然后这个题目就能有了。。

#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register int i=a;i<=b;++i)
#define throw(i,a,b) for(register int i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
namespace xin_io
{
    #define file(x) FILE *FI = freopen(#x".in","r",stdin); FI = freopen(#x".out","w",stdout)
    #define debug std::cerr<<"debug"<<endl
    #define sb(x) std::cerr<<#x" = "<<x<<' '
    #define jb(x) std::cerr<<#x" = "<<x<<endl
    #define scanf ak = scanf
    #define gec() getchar()
    #define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1 ++
    char buf[1<<20],*p1 = buf,*p2 = buf; using ll = long long; using ull = unsigned long long; int ak;
    class xin_stream{public:template<typename type>xin_stream &operator >> (type &s)
    {
        s = 0; register bool f = 0; register char ch = gc();
        while(!isdigit(ch)) f |= ch == '-',ch = gc();
        while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc(); return s = f ? -s : s,*this;
    }}io;
}
using namespace xin_io;static const int maxn = 1e6+10,inf = 1e9 + 10;ll llinf = 1e18;
#define int long long
namespace xin
{
	auto ws = [](int x) -> int
	{
		throw(i,63,1)
			if(x & (1ll << i - 1))
				return i;
		return 0ll;
	};
	auto ci = [](int x) -> int
	{
		bool ok = 0;
		throw(i,63,1)
			if(!ok and x & (1ll << i - 1))
				ok = 1;
			else if(ok and x & (1ll << i - 1))
				return i;
		return 0ll;
	};
	auto dif = [](int x,int y) -> int
	{
		throw(i,63,1)
			if((x & (1ll << i - 1)) != (y & (1ll << i - 1)))
				return i;
		return 1ll;
	};
    inline short main()
    {
		file(maxor);	
		int T; io >> T;
		while(T--)
		{
			register int l,r; io >> l >> r;
			if(ws(r) != ws(l))
				printf("%lld\n",r|((1ll << ws(r) - 1) - 1));
			else
				printf("%lld\n",r|((1ll << dif(r,l) - 1) - 1));
		}
        return 0;
    }
}
signed main() {return xin::main();}

答题

meet in middle 好题,没看出来部分分数有一个背包,但是直觉告诉我这个题目是 meet in middle,所以打了之后发现后面的取值不是很会处理。

其实二分就行

所以只能一个一个加上去,然后也有不少分数。

对于两个序列,如果你要寻找他们所有加和排名为 \(k\) 的数,使用单调指针加二分就可以解决。

#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register int i=a;i<=b;++i)
#define throw(i,a,b) for(register int i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
namespace xin_io
{
    #define file(x) FILE *FI = freopen(#x".in","r",stdin); FI = freopen(#x".out","w",stdout)
    #define debug std::cerr<<"debug"<<endl
    #define sb(x) std::cerr<<#x" = "<<x<<' '
    #define jb(x) std::cerr<<#x" = "<<x<<endl
    #define scanf ak = scanf
    #define gec() getchar()
    #define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1 ++
    char buf[1<<20],*p1 = buf,*p2 = buf; using ll = long long; using ull = unsigned long long; int ak;
    class xin_stream{public:template<typename type>xin_stream &operator >> (type &s)
    {
        s = 0; register bool f = 0; register char ch = gc();
        while(!isdigit(ch)) f |= ch == '-',ch = gc();
        while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc(); return s = f ? -s : s,*this;
    }}io;
}
using namespace xin_io;static const int maxn = 2e6+10,inf = 1e9 + 10;ll llinf = 1e18;
#define int long long
namespace xin
{
	const double eps = 1e-8;
	#define equal(x,y) (fabs(x - y) <= eps)
	int a[maxn],zhi = 0;
	int he[maxn],cnt;
	int n,c[maxn];
	double p;
	void dfs(int ms)
	{
		if(zhi == ms)
		{
			++cnt;
			try(i,1,zhi) he[cnt] += c[a[i]];
//			try(i,1,zhi) cout<<a[i]<<' ';
//			cout<<endl;
			return ;
		}
		try(i,a[zhi]+1,n)
		{
			a[++zhi] = i;
			dfs(ms);
			zhi --;
		}
	}
	int he1[maxn],he2[maxn],vis1[maxn],vis2[maxn];
	int cnt1 = 1,cnt2 = 1;
	int maxx;
	void dfs1(int ms)
	{
		if(zhi == ms)
		{
			++cnt1;
			try(i,1,zhi) he1[cnt1] += c[a[i]];
			return ;
		}
		try(i,a[zhi]+1,(n>>1))
		{
			a[++zhi] = i;
			dfs1(ms);
			zhi --;
		}
	}
	void dfs2(int ms)
	{
		if(zhi == ms)
		{
			++cnt2;
			try(i,1,zhi) he2[cnt2] += c[a[i]];
//			try(i,1,zhi) cout<<a[i]<<' '; cout<<endl;
			return ;
		}
		try(i,a[zhi]+1,n)
		{
			a[++zhi] = i;
			dfs2(ms);
			zhi --;
		}
	}
	int sum;
	inline bool check(int x,int pos)
	{
		int pi = cnt2,tot = 0;
		try(i,1,cnt1)
		{
			while(pi and he2[pi] + he1[i] > x) pi --;
			tot += pi;
		}
		return ((1.0*tot)/((long double)(1ll<<n)))>=p;
//		return tot >= pos;
	}
    inline short main()
    {
	#ifdef ONLINE_JUDGE
		file(answer);
	#endif
		scanf("%lld%lf",&n,&p);
		try(i,1,n) io >> c[i],sum += c[i];
		if(n <= 20)
		{
			try(i,1,n) dfs(i);
			he[++cnt] = 0;
			std::sort(he+1,he+cnt+1);
//			try(i,1,cnt) jb(he[i]);
			cout<<he[(int)std::ceil(cnt * p)]<<endl;
//			jb((int)std::ceil(cnt * p));
		}
		else
		{
			try(i,1,n / 2) dfs1(i); a[0] = n / 2;
			try(i,1,n / 2) dfs2(i);
			vis1[0] = vis2[0] = 1;
			int pos = (int)std::ceil((1ll << n) * p);
//			jb(pos);
			int num = 0;
//			try(i,1,cnt2) cout<<he2[i]<<' '; cout<<endl;
			std::sort(he1+1,he1+cnt1+1); std::sort(he2+1,he2+cnt2+1);
			int l = 1,r = sum,res = sum;
			while(l<=r)
			{
				register int mid = l + r >> 1;
				if(check(mid,pos)) r = mid - 1, res = mid;
				else l = mid + 1 ;
			}
			cout<<res<<endl;
		}
        return 0;
    }
}
signed main() {return xin::main();}

联合权值

这个暴力有 \(95pts\) ,然后大力卡常。。。。

正解不会。。

#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register int i=a;i<=b;++i)
#define throw(i,a,b) for(register int i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
namespace xin_io
{
    #define file(x) FILE *FI = freopen(#x".in","r",stdin); FI = freopen(#x".out","w",stdout)
    #define debug std::cerr<<"debug"<<endl
    #define sb(x) std::cerr<<#x" = "<<x<<' '
    #define jb(x) std::cerr<<#x" = "<<x<<endl
    #define scanf ak = scanf
    #define gec() getchar()
    #define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1 ++
    char buf[1<<20],*p1 = buf,*p2 = buf; using ll = long long; using ull = unsigned long long; int ak;
    class xin_stream{public:template<typename type>xin_stream &operator >> (type &s)
    {
        s = 0; register bool f = 0; register char ch = gc();
        while(!isdigit(ch)) f |= ch == '-',ch = gc();
        while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc(); return s = f ? -s : s,*this;
    }}io;
}
using namespace xin_io;static const int maxn = 3e4+10,inf = 1e9 + 10,two = 2e2+10;ll llinf = 1e18;
#define int long long
namespace xin
{
	std::bitset<maxn>link[maxn],temp;
	int n,m,t;
	int sum[maxn];
	int ans1,ans2;
	std::queue<int>q;
	bool vis[maxn];
	int w[maxn];
	std::vector<int>vec[maxn];
	int l1[maxn],l2[maxn];
    inline short main()
    {
		file(link);
		io >> n >> m >> t;
		try(i,1,m)
		{
			register int x,y; io >> x >> y;
			vec[x].push_back(y); vec[y].push_back(x);
			link[x][y] = link[y][x] = 1;
			l1[i] = x; l2[i] = y;
		}
		try(i,1,n) io >> w[i];
		try(i,1,m)
		{
			sum[l1[i]] += w[l2[i]];
			sum[l2[i]] += w[l1[i]];
		}
		try(i,1,n)
		{
			ans1 += sum[i] * sum[i];
			ans1 -= w[i] * w[i] * link[i].count();
		}
		try(i,1,m)
		{
			register int x = l1[i],y = l2[i];
			temp = link[x] & link[y];
			register int zhuan = temp.count();
			ans1 -= 2 * zhuan * w[x] * w[y];
		}
		try(x,1,n)
		{
			std::sort(vec[x].begin(),vec[x].end(),[](int x,int y){return w[x] > w[y];});
			try(i,0,(int)vec[x].size()-1) try(j,i+1,(int)vec[x].size()-1)
			{
				register int u = vec[x][i],v = vec[x][j];
				if(w[u] * w[v] < ans2) break;
				if(!link[u][v]) ans2 = w[u] * w[v];
			}
		}

		if(t xor 2) cout<<ans2<<endl;
		else cout<<0<<endl;
		if(t xor 1) cout<<(ans1 ? ans1 : -1)<<endl;
		else cout<<0<<endl;
        return 0;
    }
}
signed main() {return xin::main();}

主仆见证了 Hobo 的离别

零操作连正边,否则连反边。

然后每次 \(dfs\)

#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register int i=a;i<=b;++i)
#define throw(i,a,b) for(register int i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
namespace xin_io
{
    #define file(x) FILE *FI = freopen(#x".in","r",stdin); FI = freopen(#x".out","w",stdout)
    #define debug std::cerr<<"debug"<<endl
    #define sb(x) std::cerr<<#x" = "<<x<<' '
    #define jb(x) std::cerr<<#x" = "<<x<<endl
    #define scanf ak = scanf
    #define gec() getchar()
    #define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1 ++
    char buf[1<<20],*p1 = buf,*p2 = buf; using ll = long long; using ull = unsigned long long; int ak;
    class xin_stream{public:template<typename type>xin_stream &operator >> (type &s)
    {
        s = 0; register bool f = 0; register char ch = gc();
        while(!isdigit(ch)) f |= ch == '-',ch = gc();
        while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc(); return s = f ? -s : s,*this;
    }}io;
}
using namespace xin_io;static const int maxn = 1e6+10,inf = 1e9 + 10,two = 5e3+10;ll llinf = 1e18;
namespace xin
{
	class xin_edge{public:int next,ver;}edge[maxn];
	int head[maxn],rp;
	inline void add(int x,int y) {edge[++rp].ver = y; edge[rp].next = head[x]; head[x] = rp;}
	int n,m;
	bool vis[maxn];
	bool dfs(int x,int k)
	{
		vis[x] = 1;
		go(i,x)
		{
			if(vis[y]) continue;
			if(y == k) return 1;
			if(dfs(y,k)) return 1;
		}
		return false;
	}
    inline short main()
    {
	#ifdef ONLINE_JUDGE
		file(friendship);
	#endif
		io >> n >> m;
		try(i,1,m)
		{
			register int fg; io >> fg;
			if(!fg)
			{
				register int op,num,x; io >> op >> num >> x;
				if(!op)
				{
					++n;
					if(num == 1) add(x,n),add(n,x);
					else add(n,x);
					try(i,2,num)
					{
						io >> x;
						add(n,x);
					}
				}
				else
				{
					++n;
					if(num == 1) add(n,x),add(x,n);
					else add(x,n);
					try(i,2,num)
					{
						io >> x;
						add(x,n);
					}
				}
			}
			else
			{
				register int x,y; io >> x >> y;
				if(x == y) {printf("1\n"); continue;}
				memset(vis,0,sizeof(bool) * (n + 1));
				printf("%d\n",dfs(x,y));
			}
		}
        return 0;
    }
}
signed main() {return xin::main();}

标签:std,try,ch,noip,int,register,77,模拟,define
来源: https://www.cnblogs.com/NP2Z/p/15415917.html

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

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

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

ICode9版权所有