zoukankan      html  css  js  c++  java
  • 卷不动了(又名NOIP前的复健)

    讲道理 我已经是个老年退役选手了 可惜被逼着去北大集训 水平本来就垫底结果NOI后还无训练 目标就是每天都不爆零就好了= = 主要是精英集训这群人太卷了 一个个都说不停课不训练 结果做的比集训队都多= = 为了显得我态(yi1)度(ran2)端(huo2)正(zhe) 就稍微写一点点集训队作业 主要是挑过的人多的做的 然后就是NOIP前还是稍微复健一下 因为CSP都一个月了 手确实有点生了(写数据结构都没那么快乐了)

    Surveillance

    考虑维护每个区间往右拓展的最远的下一个区间 那么建出来是个森林(因为要跨最后) 然后直接处理一下树上问题判断一下就好 我写的太丑了 细节全是一个一个点特判出来的

    //Love and Freedom.
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define ll long long
    #define inf 20021225
    #define N 1000100
    #define pa pair<int,int>
    using namespace std;
    int read()
    {
    	int s=0,f=1; char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    	while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    	return f*s;
    }
    struct edge{int to,lt;}e[N]; int in[N],cnt,n,k,ans=inf; pa a[N];
    void add(int x,int y){e[++cnt].to=y; e[cnt].lt=in[x]; in[x]=cnt;}
    int cmp(int x,int y){int tx=a[x].first>a[x].second,ty=a[y].first>a[y].second; return tx^ty?(tx?x:y):(a[x].second<a[y].second?y:x);}
    void dfs(int x,int wei,int len)
    {
    	if(a[x].first-1<=wei&&len>1)	return ans=min(ans,len),void();
    	for(int i=in[x];i;i=e[i].lt)	dfs(e[i].to,wei,len+1);
    }
    bool ins(int x,int l,int r){return x>=l&&x<=r;}
    bool sec(int x,int y)
    {
    	int tx=a[x].first>a[x].second,ty=a[y].first>a[y].second;
    	if(tx^ty)	return a[x].second>=a[y].first-1; if(tx&ty)	return 1;
    	return a[y].first<=a[x].second+1;
    }
    int main()
    {
    	n=read(),k=read(); for(int i=1;i<=k;i++) a[i].first=read(),a[i].second=read(); sort(a+1,a+k+1); int it=1,id=1;
    	for(int i=1;i<=k;i++)	{while(it<=k&&sec(i,it))	id=cmp(id,it),it++; if(id!=i) add(id,i);}
    	for(int i=1;i<=k;i++)	if(a[i].first>a[i].second)	ans=a[i].second==a[i].first-1?1:ans,dfs(i,a[i].second,1); else if(a[i].second==n)	ans=a[i].first==1?1:ans,dfs(i,0,1);
    	if(ans==inf)	printf("impossible");
    	else	printf("%d
    ",ans);
    	return 0;
    }
    

    Intrinsic Interval

    考虑合法区间的交和并显然都是合法的 那么离线下来以后对于当前点i作为区间右端点处理每个左端点左边最右的合法点就可以了 由于是排列 所以合法的$x,x+1$的二元组只有n-1个 就是跨过这两个点的区间可以+1(这是一个对于排列连续权值段的处理方法)合法点处理就是$val_l = r-l$ 维护$val_l+l$就可以了

    //Love and Freedom.
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<set>
    #include<vector>
    #define ll long long
    #define inf 20021225
    #define N 200010
    #define ls (x<<1)
    #define rs (x<<1|1)
    #define mid (l+r>>1)
    #define pa pair<int,int>
    using namespace std;
    int read()
    {
    	int s=0,f=1; char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    	while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    	return f*s;
    }
    int mx[N<<2],tag[N<<2];
    void puttag(int x,int t){mx[x]+=t,tag[x]+=t;}
    void pushdown(int x){if(tag[x]) puttag(ls,tag[x]),puttag(rs,tag[x]),tag[x]=0;}
    void pushup(int x){mx[x]=max(mx[ls],mx[rs]);}
    void modify(int x,int l,int r,int LL,int RR,int v)
    {
    	if(l>=LL&&r<=RR)	return puttag(x,v); pushdown(x);
    	if(LL<=mid)	modify(ls,l,mid,LL,RR,v);
    	if(RR>mid)	modify(rs,mid+1,r,LL,RR,v);
    	pushup(x);
    }
    int query(int x,int l,int r,int LL,int RR,int w)
    {
    	if(r>l)	pushdown(x);
    	if(LL<=l&&RR>=r)
    	{
    		if(mx[x]<w)	return -1; if(l==r)	return l;
    		return mx[rs]==w?query(rs,mid+1,r,LL,RR,w):query(ls,l,mid,LL,RR,w);
    	}
    	int wei=-1;
    	if(RR>mid)	
    	{
    		wei=query(rs,mid+1,r,LL,RR,w);
    		if(~wei)	return wei;
    	}
    	if(LL<=mid)	return query(ls,l,mid,LL,RR,w);
    	return wei;
    }
    void build(int x,int l,int r)
    {
    	if(l==r)	return mx[x]=l,void();
    	build(ls,l,mid),build(rs,mid+1,r); pushup(x);
    }
    set<pa> lpos; vector<pa> pos[N]; int n,m,a[N],lst[N],al[N],ar[N];
    int main()
    {
    	n=read(); for(int i=1;i<=n;i++)	a[i]=read(); m=read(); build(1,1,n);
    	int l,r; for(int i=1;i<=m;i++)	l=read(),r=read(),pos[r].push_back(make_pair(l,i));
    	for(int i=1;i<=n;i++)
    	{
    		lst[a[i]]=i;
    		if(a[i]>1&&lst[a[i]-1])	modify(1,1,n,1,lst[a[i]-1],1);
    		if(a[i]<n&&lst[a[i]+1])	modify(1,1,n,1,lst[a[i]+1],1);
    		for(int j=0;j<pos[i].size();j++)	lpos.insert(pos[i][j]);
    		while(!lpos.empty())
    		{
    			pa wei=*(--lpos.end()); int qwq=query(1,1,n,1,wei.first,i);
    			if(qwq==-1)	break; al[wei.second]=qwq; ar[wei.second]=i; lpos.erase(--lpos.end());
    		}
    	}
    	for(int i=1;i<=m;i++)	printf("%d %d
    ",al[i],ar[i]);
    	return 0;
    }
    

    Integral Polygons

    垃圾题 拆成叉积和 显然只有奇偶的区别 讨论一下就好了

    //Love and Freedom.
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define ll long long
    #define inf 20021225
    #define N 200010
    using namespace std;
    int read()
    {
    	int s=0,f=1; char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    	while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    	return f*s;
    }
    struct poi{int x,y;}a[N]; int n,wei[N],pre[N][2][2][2];
    int cross(poi a,poi b){return a.x*b.y+b.x*a.y;}
    int main()
    {
    	n=read(); for(int i=1;i<=n;i++)	a[i].x=read()&1,a[i].y=read()&1;
    	for(int i=1;i<=n;i++)	wei[i]=(wei[i-1]+cross(a[i-1?i-1:n],a[i]))&1; ll ans=0;
    	for(int i=1;i<=n;i++)
    	{
    		for(int s=0;s<2;s++)	for(int x=0;x<2;x++)	for(int y=0;y<2;y++)
    			if(!((a[i].x*y+a[i].y*x-s+wei[i])&1))	ans+=pre[i-1][s][x][y];
    		for(int s=0;s<2;s++)	for(int x=0;x<2;x++)	for(int y=0;y<2;y++)
    			pre[i][s][x][y]=pre[i-1][s][x][y];
    		pre[i][wei[i]][a[i].x][a[i].y]++;
    	}
    	if(wei[n])	puts("0"); else printf("%lld
    ",ans-n);
    	return 0;
    }
    
    ### Hack Protection
    果然还是数据结构比较快乐 对于每个左端点显然&的值变化只有O(log)个 然后看区间内有无异或满足即可
    //Love and Freedom.
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<set>
    #include<map>
    #include<vector>
    #define ll long long
    #define inf 20021225
    #define N 100010
    #define pa pair<int,int>
    using namespace std;
    int read()
    {
    	int s=0,f=1; char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    	while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    	return f*s;
    }
    int n,a[N],pre[N],nmd[N][32]; pa nxt[32]; set<int> ze[32]; map<int,vector<int> > w;
    int main()
    {
    	n=read(); for(int i=1;i<=n;i++)	pre[i]=pre[i-1]^(a[i]=read()),w[pre[i]].push_back(i);
    	for(int i=n;i;i--)	for(int b=0;b<31;b++)	if(!(a[i]>>b&1))	nmd[i][b]=i; else nmd[i][b]=nmd[i+1][b];
    	ll ans=0;
    	for(int i=1;i<=n;i++)
    	{
    		int tot=0,val=2147483647; 
    		for(int b=0;b<31;b++)
    			if(nmd[i][b])	nxt[++tot]=make_pair(nmd[i][b],b);
    		sort(nxt+1,nxt+tot+1); int lst=i;
    		for(int k=1,j;k<=tot;k=j)
    		{
    			int pos=nxt[k].first,qwq=val^pre[i-1];
    			if(w.find(qwq)!=w.end())
    			{
    				vector<int>::iterator bg=w[qwq].begin(),ed=w[qwq].end();
    				ans+=lower_bound(bg,ed,pos)-lower_bound(bg,ed,lst);
    			}
    			for(j=k;j<=tot&&nxt[j].first==nxt[k].first;j++) val^=1<<nxt[j].second; lst=pos;
    		}
    		int qwq=val^pre[i-1];
    		if(w.find(qwq)!=w.end())
    		{
    			vector<int>::iterator bg=w[qwq].begin(),ed=w[qwq].end();
    			ans+=lower_bound(bg,ed,n+1)-lower_bound(bg,ed,lst);
    		}
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    The Imp

    博弈论题 有一个不是很显然的结论就是每次取的价值是单调不降的 然后就可以直接dp了= =

    //Love and Freedom.
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define ll long long
    #define inf 20021225
    #define N 200010
    using namespace std;
    int read()
    {
    	int s=0,f=1; char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    	while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    	return f*s;
    }
    int n,k,f[N][10]; pair<int,int> w[N];
    int main()
    {
    	int t=read();
    	while(t--)
    	{
    		n=read(),k=read(); for(int i=1;i<=n;i++)	w[i].first=read(),w[i].second=read(); sort(w+1,w+n+1); reverse(w+1,w+n+1);
    		for(int i=1;i<=n;i++)	f[i][0]=max(f[i-1][0],w[i].first-w[i].second);
    		for(int i=1;i<=n;i++)	for(int j=1;j<=k;j++)	f[i][j]=max(f[i-1][j],min(w[i].first-w[i].second,f[i-1][j-1]-w[i].second));
    		printf("%d
    ",f[n][k]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    正则表达式常用语法
    JDK源码分析hashmap
    追加数据
    验证域名!!!!!!!!!
    Hadoop(一)之初识大数据与Hadoop
    Hadoop(十)Hadoop IO之数据完整性
    Hadoop(九)Hadoop IO之Compression和Codecs
    Hadoop(八)Java程序访问HDFS集群中数据块与查看文件系统
    Hadoop(七)HDFS容错机制详解
    python连接数据库
  • 原文地址:https://www.cnblogs.com/hanyuweining/p/14070828.html
Copyright © 2011-2022 走看看