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

最大或

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

首先可以发现在两个二进制数的位数不相同的时候,那么答案就一定是所有都是 \(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();}