[考试总结]noip模拟17

爆零了!

菜爆了

弱展了


垃爆了

没有什么可以掩饰你的菜了

这次考试为我带来了第一个 \(\color{red}{ \huge{0}}\) 分,十分欣慰。。。。

最近的暴力都打不对,你还想什么正解???

考完之前就差不多知道自己大概是一个零分,然而抱着侥幸打开赛时排行榜的时候,直接翻到最下方就直接看到了自己的名字。。。。

\(fa\) 可说。。

自己看题都看不全,谁告诉过你 题目背景 就一定没有用了???

然而 \(sb\;XIN\) 直接跳过,并且默认无向图。。。

\(\huge{\text{你不爆零谁爆零?}}\)

T2 贪心都打不对,真垃。

\(\huge{\text{你不爆零谁爆零?}}\)

T3 打的都不配叫做爆搜。

\(\huge{\text{你不爆零谁爆零?}}\)

菜就是了。。。

世界线:

\(bitset\) + \(toposort\)

就这?

就这。。

\(bitset\) 常数极小,其实平常的 \(bool\) 数组都可以换成 \(bitset\)

然后 \(toposort\) 就很普通



#include<bits/stdc++.h>
using std::cout; using std::endl;
#define debug cout<<"debug"<<endl
#define int long long
namespace xin_io
{
	#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
	#define scanf eat1 = scanf
	#define freopen eat2 = freopen
	int eat1; FILE *eat2; char buf[1<<20],*p1 = buf,*p2 = buf;
	inline void openfile() {freopen("t.txt","r",stdin);} inline void outfile() {freopen("o.txt","w",stdout);}
	template<class type>inline type get()
	{
		type s = 0,f = 1; register char ch = gc();
		while(!isdigit(ch)) {if(ch == '-') f = -1; ch = gc();}
		while(isdigit(ch))  {s = s * 10 + ch - '0'; ch = gc();}
		return s * f;
	}
}
using namespace xin_io; static const int maxn = 6e4+50,maxm = 1e6+10,inf = 0x7f7f7f,mod = (1<<30);
#define try(i,a,b) for(register signed i=a;i<=b;++i)
#define throw(i,a,b) for(register signed i=a;i>=b;--i)
typedef long long ll;
namespace xin
{
	int l,r,an[maxn];
	class xin_edge{public:int next,ver;}edge[maxm];
	int head[maxn],zhi = 0;
	inline void add(int x,int y) {edge[++zhi].ver = y;edge[zhi].next = head[x]; head[x] = zhi;}
	int n,m;
	int ou[maxn];
	int outd[maxn],num[maxn];
	bool vis[maxn];
	int ret = 0;
	std::bitset<(maxn/20)>lian[maxn];
	int ans = 0,ind[maxn];
	inline void topo()
	{
		std::queue<int>q;
		try(i,1,n) if(!outd[i]) q.push(i);//,cout<<"i = "<<i<<endl;;
		while(!q.empty())
		{
			register int x = q.front(); q.pop(); 
			if(x>=l and x<=r)lian[x][(x-l)] = 1;
			for(register int i=head[x];i;i=edge[i].next)
			{
				register int y = edge[i].ver;
				if(x>=l and x<=r)lian[x][(x-l)] = 1;
				lian[y] |= lian[x];
				if(y>=l and y<=r)lian[y][(y-l)] = 1;
				outd[y]--;
				if(!outd[y]) q.push(y);
			}
		}
		try(i,1,n)an[i] += lian[i].count();
	}
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		n = get<signed>(); m = get<signed>();
		try(i,1,m)
		{
			register int x = get<signed>(),y = get<signed>();
			add(y,x);ou[x]++; outd[x]++; ind[y]++;
		}
		l=1;r=std::min(3000ll,n);
		while(l<=n)
		{
			try(i,1,n) lian[i] = 0;
			topo();
			try(i,1,n)outd[i]=ou[i];
			l=r+1,r=std::min(l+3000ll-1,n);
		}
		try(i,1,n)
			ans += an[i] - ind[i];
		cout<<ans - n<<endl;
		return 0;
	}
}
signed main() {return xin::main();}

时间机器:

一个大贪心。

然而你却看不出来。

一个 \(\mathcal O(n^2)\) 暴力狂扫直接 \(70pts\)

然后进一步 \(map\) 优化直接 \(100pts\)

真垃。



#include<bits/stdc++.h>
using std::cout; using std::endl;
#define debug cout<<"debug"<<endl
#define int long long
namespace xin_io
{
	#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
	#define scanf eat1 = scanf
	#define freopen eat2 = freopen
	int eat1; FILE *eat2; char buf[1<<20],*p1 = buf,*p2 = buf;
	inline void openfile() {freopen("t.txt","r",stdin);} inline void outfile() {freopen("o.txt","w",stdout);}
	template<class type>inline type get()
	{
		type s = 0,f = 1; register char ch = gc();
		while(!isdigit(ch)) {if(ch == '-') f = -1; ch = gc();}
		while(isdigit(ch))  {s = s * 10 + ch - '0'; ch = gc();}
		return s * f;
	}
}
using namespace xin_io; static const int maxn = 1e6+10,maxq = 3e5+10,inf = 0x7f7f7f7f;
#define try(i,a,b) for(register signed i=a;i<=b;++i)
#define throw(i,a,b) for(register signed i=a;i>=b;--i)
typedef long long ll;
namespace xin
{
	int T,n,m;
	class node
	{
		public:
			ll l,r,cnt,op;
			friend bool operator < (const node &a,const node &b)
			{return (a.l==b.l)?a.op<b.op:a.l<b.l;}
	}t[maxn];
	std::map<ll,ll> mp;
	std::map<ll,ll>::iterator it;
	inline short main()
	{
		T = get<signed>();
		while(T--)
		{
		    n = get<signed>();m = get<signed>();
		    mp.clear();
		    ll cnt=0;
		    try(i,1,n) t[++cnt].l=get<signed>(),t[cnt].r=get<signed>(),t[cnt].cnt=get<signed>(),t[cnt].op=1;
		    try(i,1,m) t[++cnt].l=get<signed>(),t[cnt].r=get<signed>(),t[cnt].cnt=get<signed>(),t[cnt].op=-1;
		    int ok=1;
		    std::sort(t+1,t+1+cnt);
		    try(i,1,cnt)
		    {
		        //printf("t.op=%lld\n",t[i].op);
		        if(t[i].op==-1)
		            mp[t[i].r]+=t[i].cnt;
		        else
		        {
		            while(t[i].cnt)
		            {
		                it=mp.lower_bound(t[i].r);
		        //        printf("mp[%lld]=%lld\n",t[i].r,mp[t[i].r]);
		                if(it==mp.end()) {ok = 0;break; }
		                if(t[i].cnt >= it->second) t[i].cnt -= it->second,mp.erase(it);
		                else it->second-=t[i].cnt,t[i].cnt = 0;
		            }
		            if(!ok)break;
		        }
		    }
		    !ok ? printf("No\n") : printf("Yes\n");
		}
		return 0;
	}
}
signed main() {return xin::main();}

weight:

首先最小生成树那就先求出来一个。

然后 \(tarjan\) 判断割边就有很多分数。

然后树剖线段树维护就可以 \(\mathcal O(nlogn^2)\)

然而调不出来

posted @ 2021-07-20 10:52  NP2Z  阅读(33)  评论(0编辑  收藏  举报