这次比赛不是很难(但是我也只有140),但竟然是第三名(捂脸)
T1:
clique
【题目描述】
数轴上有 n 个点,第 i 个点的坐标为 xi,权值为 wi。两个点 i,j 之
间存在一条边当且仅当 abs(xi-xj)>=wi+wj。
你需要求出这张图的最大团的点数。(团就是两两之间有边的顶点
集合)
【输入数据】
第一行一个整数 n,接下来 n 行每行两个整数 xi,wi。
【输出数据】
一行一个整数表示答案。
【样例输入】
4
2 3
3 1
6 1
0 2
【样例输出】
3
【数据范围】
对于 20%的数据, n<=10。
对于 60%的数据, n<=1000。
对于 100%的数据, n<=200000, 0<=|xi|,wi<=10^9。
考场上看了几眼就去做T2,结果发现T2不会,打了暴力又回来
画图手玩样例,就像到正解了。。。。。。
不就是一个选最多不重合区间吗
但是后来某巨佬讲课才知道用最长上升子序列+线段树优化
#include<bits/stdc++.h> using namespace std; #define ll long long #define cg ch=getchar() const int _=500002; ll number,x[_],w[_],f[_],tl,ans=1; struct node{ll l,r;}room[_]; ll read(){ ll s=0,w=1;char cg; while(ch<'0'||ch>'9')w=(ch=='-')?-1:1,cg; while(ch>='0'&&ch<='9')s=s*10+ch-'0',cg; return s*w; } bool cmp(node a,node b){ if(a.r!=b.r)return a.r<b.r; return a.l<b.l; } int main(){ freopen("clique.in","r",stdin); freopen("clique.out","w",stdout); number=read(); for(int i=1;i<=number;i++)x[i]=read(),w[i]=read(),room[i].l=x[i]-w[i],room[i].r=x[i]+w[i]; sort(room+1,room+number+1,cmp); f[1]=1;tl=room[1].r; for(int i=2;i<=number;i++){ f[i]=f[i-1]; if(room[i].l>=tl){ f[i]=f[i-1]+1;tl=room[i].r; } } cout<<f[number]; return 0; }
T2:
mod
【题目描述】
给定一个长度为 n 的非负整数序列 a,你需要支持以下操作:
1:给定 l,r,输出 a[l]+a[l+1]+…+a[r]。
2:给定 l,r,x,将 a[l],a[l+1],…,a[r]对 x 取模。
3:给定 k,y,将 a[k]修改为 y。
【输入数据】
第一行两个整数 n,m。第二行 n 个整数 a[1]~a[n]。接下来 m 行每
行 3 或 4 个整数表示操作。
【输出数据】
对于每个操作 1,输出一行一个整数表示答案。
【样例输入】
5 5
1 2 3 4 5
2 3 5 4
3 3 5
1 2 5
2 1 3 3
1 1 3
【样例输出】
8 5
【数据范围】
对于 40%的数据, n,m<=1000。
对于 100%的数据,n,m<=100000,1<=l<=r<=n,1<=k<=n,1<=x<=10^9,
0<=a[i],y<=10^9。
看到题目时,我的心中毫无波澜,想着一个简简单单的板子题,不就是送分的吗
结果发现要%。。。。。。
做完T1再来想,发现用线段树维护区间和和区间最大值,取膜直接暴力
但是当区间最大值 < 当前需要%的,就可以退出(这应该是个小小的优化)
可是我写挂了。。。。。。
#include<bits/stdc++.h> using namespace std; #define ll long long #define cg ch=getchar() const int _=100002; ll number,magic,ans; struct node{ll l,r,w,maxx;}tree[_*4+1]; ll read(){ ll s=0,w=1;char cg; while(ch<'0'||ch>'9')w=(ch=='-')?-1:1,cg; while(ch>='0'&&ch<='9')s=s*10+ch-'0',cg; return s*w; } void Build(ll k,ll l,ll r){ tree[k].l=l;tree[k].r=r; if(l==r){ tree[k].w=tree[k].maxx=read(); return; } ll mid=(tree[k].l+tree[k].r)>>1; Build(k*2,l,mid);Build(k*2+1,mid+1,r); tree[k].w=tree[k*2].w+tree[k*2+1].w; tree[k].maxx=max(tree[k*2].maxx,tree[k*2+1].maxx); } void getsum(ll k,ll l,ll r){ if(l<=tree[k].l&&tree[k].r<=r){ ans+=tree[k].w;return; } ll mid=(tree[k].l+tree[k].r)>>1; if(l<=mid)getsum(k*2,l,r); if(r>mid)getsum(k*2+1,l,r); } void change1(ll k,ll l,ll r,ll x){ if(tree[k].maxx<x)return; if(tree[k].l==tree[k].r){ tree[k].w%=x;tree[k].maxx%=x; return; } ll mid=(tree[k].l+tree[k].r)>>1; if(l<=mid)change1(k*2,l,r,x); if(mid<r)change1(k*2+1,l,r,x); tree[k].w=tree[k*2].w+tree[k*2+1].w; tree[k].maxx=max(tree[k*2].maxx,tree[k*2+1].maxx); } void change2(ll k,ll x,ll y){ if(tree[k].l==tree[k].r){ tree[k].w=tree[k].maxx=y;return; } ll mid=(tree[k].l+tree[k].r)>>1; if(x<=mid)change2(k*2,x,y); else change2(k*2+1,x,y); tree[k].w=tree[k*2].w+tree[k*2+1].w; tree[k].maxx=max(tree[k*2].maxx,tree[k*2+1].maxx); } int main(){ freopen("mod.in","r",stdin); freopen("mod.out","w",stdout); number=read();magic=read(); Build(1,1,number); for(int i=1;i<=magic;i++){ ans=0; ll pd=read(),l=read(),r=read(),x; if(pd==1){ getsum(1,l,r);cout<<ans<<endl; } if(pd==2)x=read(),change1(1,l,r,x); if(pd==3)change2(1,l,r); } return 0; }
T3:没学过,忽略