计划:
接下来一个星期每天打一场比赛(at or cf of 日常 )+ 自己的专题要做。。。
缺的专题:
方式;(入门题应该有做了,可是还是对于综合应用不太会。。)
顺序:
1: 单调队列,单调栈,链表,树状数组,线段树等基础的数据结构
2:简单dp 的想象
3:费用流
4:lca 的三种方法:
2017年08月07日:
简单二分:
https://vjudge.net/contest/176120#problem/R
做到想哭,,看了师兄代码。。都不知道自己为什么错;
而且不敢否认我的二分的形式自己都不知道怎么固定写
师兄的
while(l<r){
LL mid=(l+r)>>1;
if(ok(mid))r=mid;
else l=mid+1;
}
线段树:
https://vjudge.net/contest/176120#problem/S
自己太水了,, 没有直接想到两个线段树,
看了师兄的,写的真好,,直接用结构体/
#define LL long long
#define inf 0x3f3f3f3f
#define ls (i<<1)
#define rs (ls|1)
#define md ((ll+rr)>>1)
#define mxn 100020
int a[mxn];
int n,m,k;
struct seg_tree{
LL add[mxn<<2],sum[mxn<<2];
void init(){ mem(add,0);mem(sum,0); }
void build(int ll,int rr,int i){
add[i]=0;
if(ll==rr){
sum[i]=a[ll];return;
}
build(ll,md,ls);
build(md+1,rr,rs);
sum[i]=sum[ls]+sum[rs];
}
void down(int i,int ll,int rr){
if(add[i]){
int len=rr-ll+1;
add[ls]+=add[i],add[rs]+=add[i];
sum[ls]+=add[i]*(len-len/2);
sum[rs]+=add[i]*(len/ 2);
add[i]=0;
}
}
void update(int l,int r,LL val,int ll,int rr,int i){
if(ll==l&&rr==r){
add[i]+=val;sum[i]+=(r-l+1)*val;return;
}
down(i,ll,rr);
if(r<=md)update(l,r,val,ll,md,ls);
else if(l>md)update(l,r,val,md+1,rr,rs);
else{
update(l,md,val,ll,md,ls);
update(md+1,r,val,md+1,rr,rs);
}
sum[i]=sum[ls]+sum[rs];
}
LL query(int x,int ll,int rr,int i){
if(ll==rr)return sum[i];
down(i,ll,rr);
if(x<=md)return query(x,ll,md,ls);
return query(x,md+1,rr,rs);
}
}t1,t2;
int L[mxn],R[mxn],D[mxn];
int main(){
int n,m,k;sf("%d%d%d",&n,&m,&k);
rep(i,1,n){sf("%d",&a[i]); }
rep(i,1,m){ sf("%d%d%d",&L[i],&R[i],&D[i]);}
t2.init();
rep(i,1,k){
int l,r;sf("%d%d",&l,&r);
t2.update(l,r,1,1,m,1);
}
t1.build(1,n,1);
rep(i,1,m){
LL t=t2.query(i,1,m,1);
t1.update(L[i],R[i],D[i]*t,1,n,1);
}
rep(i,1,n){
pf("%I64d%c",t1.query(i,1,n,1),i==n?'\n':' ');
}
}
https://vjudge.net/contest/176120#problem/U
这样能保证唯一性,太巧了。。。
set<int>s[mxn];
struct Point{
int x,y;
}point[mxn];
bool check(int u,int v){
if((point[u].x+point[v].x)&1)return 0;
if((point[u].y+point[v].y)&1)return 0;
return 1;
}
int main(){
int n;sf("%d",&n);
rep(i,1,n){ sf("%d%d",&point[i].x,&point[i].y);s[point[i].x+N].insert(point[i].y); }
sort(point+1,point+1+n);
int ans=0;
for(int i=1;i<=n;++i){
for(int j=i+1;j<=n;++j){
if(!check(i,j))continue;
int dx=(point[i].x+point[i].x)/2;
int dy=(point[i].y+point[i].y)/2;
if(s[dx+N].count(dy))ans++;
}
}
pf("%d\n",ans);
}
https://vjudge.net/contest/176120#problem/V普通的树状数组,
注意树状数组没有0的,有+1; 还有要自己把图画出来。。
https://vjudge.net/contest/176120#problem/X
现在都还觉的有点难的题目。。。 看不懂师兄的为什么过了
https://vjudge.net/contest/176120#problem/F
dfs
可是师兄写的很优雅。。
int n,k;
int is[N],from[N];
int flag;
int vis[N];
bool dfs(int u,int v){
if(is[v]==0){
pf("%d %d\n",u,v);
flag=1;
is[v]=v;
from[v]=v;
is[u]=0;
vis[v]=1;
return true;
}
if(vis[v]==-1)return false;
vis[u]=-1;
if(dfs(v,is[v])){
pf("%d %d\n",u,v);
flag=1;
is[v]=v;
from[v]=v;
is[u]=0;
vis[v]=1;
vis[u]=0;
return true;
}
else vis[u]=0;return false;
}
int main(){
while(~sf("%d%d",&n,&k)){
int cnt=0;
mem(is,0);
rep(i,1,k){
int num;sf("%d",&num);
rep(j,1,num){
int val;sf("%d",&val);
is[val]=++cnt;
from[cnt]=val;
}
}
flag=0;
for(int i=1;i<=cnt;++i){
if(is[i]==i)continue;
if(dfs(from[i],i))continue;
int fre;
for(int j=n;j>=1;j--){
if(!is[i]){fre=i;break;}
}
pf("%d %d\n",from[i],fre);
is[fre]=is[from[i]];
is[from[i]]=0;
dfs(i,is[i]);
pf("%d %d\n",fre,i);
flag=1 ;
is[i]=i;
is[fre]=0;
vis[i]=1;
}
if(!flag)pf("");
}
}
https://vjudge.net/contest/52919#problem/G
又只能看师兄是怎么操作并查集的。。
代码是错的不知道哪里错了。。
int n,m;
int fa[N];
int cnt[N];
LL sum[N];
int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
void init(){
mem(sum,0);
rep(i,1,n){
fa[i]=i+ym;sum[i+ym]=i;fa[i+ym]=i+ym;cnt[i+ym]=1;
}
}
int main(){
while(~sf("%d%d",&n,&m)){
rep(i,1,n)fa[i]=i;
rep(i,1,m){
int op;sf("%d",&op);
if(op==1){
int u,v;sf("%d%d",&u,&v);
int fu=find(u),fv=find(v);
if(fu==fv)continue;
fa[fv]=fu;
sum[fu]+=sum[fv];
cnt[fu]+=cnt[fv];
}
else if(op==2){
int u,v;sf("%d%d",&u,&v);
int fu=find(u),fv=find(v);
fa[u]=fv;
cnt[fu]--;
cnt[fv]++;
sum[fu]-=u;
sum[fv]+=u;
}
else{
int c;sf("%d",&c);int u=find(c);
pf("%d %lld\n",cnt[u],sum[u]);
}
}
}
}
https://vjudge.net/contest/52919#problem/H
走神加继续抄师兄的。。
int n,q;
int stk[N<<2],a[N<<2],R[N<<2],L[N<<2];
void calc(){
int top=1;
a[n+1]=inf; stk[1]=1;
for(int i=2;i<=n+1;++i){
if(a[i]==a[stk[top]]){
stk[++top]=i;continue;
}
while(top){
R[stk[top]]=i-1;
L[stk[top--]]=stk[1];
}
stk[++top]=i;
}
}
int ll[N<<2],rr[N<<2],mx[N<<2];
void build(int l,int r,int rt){
ll[rt]=l;rr[rt]=r;
if(l==r){
mx[rt]=1;return ;
}
int m=(l+r)>>1;
build(l,m,ls);
build(m+1,r,rs);
mx[rt]=max(mx[ls],mx[rs]);
if(a[m]==a[m+1]){
int head=max(L[m],l);
int tail=min(R[m],r);
if(tail-head+1>mx[rt])
mx[rt]=tail-head+1;
}
}
int query(int l,int r,int rt){
if(ll[rt]==l&&rr[rt]==r){
return mx[rt];
}
int m=(ll[rt]+rr[rt])>>1;
if(r<=m)return query(l,r,ls);
if(l>m)return query(l,r,rs);
int tmax;
tmax=max(query(l,m,ls),query(m+1,r,rs));
if(a[m]==a[m+1]){
int head=max(L[m],l);
int tail=min(R[m],r);
if(tmax<tail-head+1){
tmax=tail-head+1;
}
}
return tmax;
}
int main(){
//freopen("test.txt","r",stdin);
while(~sf("%d%d",&n,&q)&&n!=0){
rep(i,1,n)sf("%d",&a[i]);
calc();
build(1,n,1);
rep(i,1,q){
int l,r;sf("%d%d",&l,&r);
pf("%d\n",query(l,r,1));
}
}
}
https://vjudge.net/contest/52919#problem/I
这题建哥问过我,结果我又不会了。。
又看了师兄的,也许这是套路