20160929训练记录

选数

排序原数列,二分答案,对于差值<mid的相邻对进行删除

#include<map>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<complex>
#include<iostream>
#include<assert.h>
#include<algorithm>
using namespace std;
#define inf 1001001001
#define infll 1001001001001001001LL
#define ll long long
#define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl
#define gmax(a,b) (a)=max((a),(b))
#define gmin(a,b) (a)=min((a),(b))
#define Ri register int
#define gc getchar()
#define il inline
il int read(){
    bool f=true;Ri x=0;char ch;while(!isdigit(ch=gc))if(ch==‘-‘)f=false;while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-‘0‘;ch=gc;}return f?x:-x;
}
#define gi read()
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
int n,k,a[100002],p[100002],g[100002];
bool chk(int x){
    int cnt=0,_p=a[1],mn;
    for(int i=2;i<=n;i++){
        if(a[i]-_p<x)++cnt;
        else _p=a[i];
    }
    return n-cnt>=k;
}
int main(){
    FO(choose);
    n=gi;k=gi;
    for(int i=1;i<=n;i++)a[i]=gi;
    sort(a+1,a+n+1);
    for(int i=2;i<=n;i++)g[i]=a[i]-a[i-1];
    int l=1,r=1000000001,ans;
    while(l<=r){
        int mid=(l+r)/2;
        if(chk(mid)){
            ans=mid;
            l=mid+1;
        }
        else r=mid-1;
    }
    cout<<ans;
}

划区灌溉

易得f[i]=min{f[j]}+1 ()

然后用个单调队列

#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<complex>
#include<iostream>
#include<assert.h>
#include<algorithm>
using namespace std;
#define inf 1001001001
#define infll 1001001001001001001LL
#define ll long long
#define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl
#define gmax(a,b) (a)=max((a),(b))
#define gmin(a,b) (a)=min((a),(b))
#define Ri register int
#define gc getchar()
#define il inline
il int read(){
    bool f=true;Ri x=0;char ch;while(!isdigit(ch=gc))if(ch==‘-‘)f=false;while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-‘0‘;ch=gc;}return f?x:-x;
}
#define gi read()
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
const int maxn=1000033;
int dq[1234567],f[1234567],map[1234567];
int n,m,L,A,B;
int main(){
    FO(divide);
    n=gi;L=gi;A=gi;B=gi;
    memset(f,127/2,sizeof(f));
    int a,b;
    for(int i=1;i<=n;i++)
        a=gi,b=gi,map[min(a+1,b)]++,map[b]--;
    a=(A-B)<<1,b=0;int H=1,T=0;
    f[0]=0;
    int now=0;
    for(int i=1;i<A*2;i++)    now+=map[i];
    for(int i=A<<1;i<=L;i+=2,a+=2,b+=2){
        while(H<=T&&f[dq[T]]>=f[b])    T--;
        dq[++T]=b;
        if(f[dq[T]]>=inf)    T--;
        now+=map[i]+map[i-1];
        if(now){
            f[i]=inf;
            continue;
        }
        while(H<=T&&dq[H]<a)    H++;
        if(H<=T&&f[dq[H]]<inf)f[i]=f[dq[H]]+1;
        else f[i]=inf;
    }
    printf("%d\n",f[L]<inf?f[L]:-1);
    return 0;
}

树林

从树林连一条线到边界。然后根据在边界两侧的情况bfs

#include<map>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<complex>
#include<iostream>
#include<assert.h>
#include<algorithm>
using namespace std;
#define inf 1001001001
#define infll 1001001001001001001LL
#define ll long long
#define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl
#define gmax(a,b) (a)=max((a),(b))
#define gmin(a,b) (a)=min((a),(b))
#define Ri register int
#define gc getchar()
#define il inline
il int read(){
    bool f=true;Ri x=0;char ch;while(!isdigit(ch=gc))if(ch==‘-‘)f=false;while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-‘0‘;ch=gc;}return f?x:-x;
}
#define gi read()
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
int n,m,sx,sy,x,y;
struct data{
    int x,y,f;
};
int dx[]={0,0,1,1,1,-1,-1,-1};
int dy[]={1,-1,-1,0,1,1,-1,0};
int a[55][55],b[55][55],flag[2][55][55];
int main(){
    FO(grove);
    n=gi;m=gi;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            char ch=gc;
            while(ch!=‘.‘&&ch!=‘X‘&&ch!=‘*‘)ch=gc;
            if(ch==‘X‘)a[i][j]=1,x=i,y=j;
            if(ch==‘*‘)sx=i,sy=j;
    }
    queue<data>q;
    q.push((data){sx,sy,0});
    for(int i=1;i<=n-x;i++)b[i+x][y]=1;
    while(!q.empty()){
        data c=q.front();q.pop();
        for(int i=0;i<8;i++){
            int X=c.x+dx[i],Y=c.y+dy[i];
            if(X<=n&&X>0&&Y<=m&&Y>0&&!a[X][Y]){
                if((b[c.x][c.y]||b[X][Y])&&Y<=c.y)continue;
                if(b[X][Y]&&!flag[1][X][Y]){
                    flag[1][X][Y]=flag[c.f][c.x][c.y]+1;
                    q.push((data){X,Y,1});
                }else{
                    if(!flag[c.f][X][Y]){
                        flag[c.f][X][Y]=flag[c.f][c.x][c.y]+1;
                        q.push((data){X,Y,c.f});
                    }
                }
            }
        }
    }
    cout<<flag[1][sx][sy];
}

迷宫花坛

仙人掌最短路。

把环缩了。然后根据两点的位置分类讨论

#include<map>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<complex>
#include<iostream>
#include<assert.h>
#include<algorithm>
using namespace std;
#define inf 1001001001
#define infll 1001001001001001001LL
#define ll long long
#define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl
#define gmax(a,b) (a)=max((a),(b))
#define gmin(a,b) (a)=min((a),(b))
#define Ri register int
#define gc getchar()
#define il inline
il int read(){
    bool f=true;Ri x=0;char ch;while(!isdigit(ch=gc))if(ch==‘-‘)f=false;while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-‘0‘;ch=gc;}return f?x:-x;
}
#define gi read()
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);

const int N=100010,M=300010;
using namespace std;
int n,m,Q,dis[N],sta[N],top;
int rdis[N],rcnt,fa[N][22],dfn[N],pre[N],bel[N],rlen[N],dep[N];
struct edge{
    int to,next,val;
}e[M*2];
int last[N],cnt=1,tim;
bool inq[N],del[M],vis[N];
void add(int a,int b,int c){
    e[++cnt]=(edge){b,last[a],c};last[a]=cnt;
}
void ins(int a,int b,int c){add(a,b,c),add(b,a,c);}
void spfa(){
    queue<int>q;
    for(int i=1;i<=N;i++)dis[i]=inf;
    dis[1]=0;q.push(1);inq[1]=1;
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int y=last[x];y;y=e[y].next){
            if (dis[e[y].to]>dis[x]+e[y].val){
                dis[e[y].to]=dis[x]+e[y].val;
                if (!inq[e[y].to]){
                           q.push(e[y].to);
                        inq[e[y].to]=1;
                }
            }
        }
        inq[x]=0;
    }
}
void getring(int st,int ed,int id){
    del[id]=del[id^1]=1;
    rlen[++rcnt]+=e[id].val;
    for(int x=ed;x!=st;x=e[pre[x]^1].to){
        bel[x]=rcnt;
        del[pre[x]]=del[pre[x]^1]=1;
        ins(st,x,0);
        rlen[rcnt]+=e[pre[x]].val;
    }
}  

void dfs(int x){
    dfn[x]=++tim;
    for (int y=last[x];y;y=e[y].next)
        if(y!=(pre[x]^1)&&(y<=(m*2+1))){
            if(!dfn[e[y].to])
                pre[e[y].to]=y,rdis[e[y].to]=rdis[x]+e[y].val,dfs(e[y].to);
            else if(dfn[e[y].to]<dfn[x])
                        getring(e[y].to,x,y);
        }
}  

void dfs2(int x){
    vis[x]=1;
    for(int i=1;i<=17;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
    for(int y=last[x];y;y=e[y].next)
        if(!del[y]&&e[y].to!=fa[x][0])
            dep[e[y].to]=dep[x]+1,fa[e[y].to][0]=x,dfs2(e[y].to);
}  

int query(int x,int y){
    if(dep[x]<dep[y]) swap(x,y);
    int a=x,b=y;
    for(int h=dep[x]-dep[y],i=17;h&&i>=0;i--) if(h&(1<<i))h-=(1<<i),x=fa[x][i];
    if(x==y) return dis[a]-dis[b];
    for(int i=17;i>=0;i--)
        if(fa[x][i]!=fa[y][i])
            x=fa[x][i],y=fa[y][i];
    int lca=fa[x][0];
    if(bel[x]&&bel[x]==bel[y]){
        int d=abs(rdis[x]-rdis[y]);d=min(d,rlen[bel[x]]-d);
        return dis[a]+dis[b]-dis[x]-dis[y]+d;
    }
    return dis[a]+dis[b]-2*dis[lca];
}  

int main(){
    FO(garden);
    n=gi;m=gi;
    for(int i=1,x,y,z;i<=m;i++) x=gi,y=gi,z=gi,ins(x,y,z);
    spfa();
    pre[1]=-1;
    dfs(1);dfs2(1);
    Q=gi;
    for(int i=1;i<=Q;i++) printf("%d\n",query(gi,gi));
    return 0;
}
时间: 2024-11-05 11:49:30

20160929训练记录的相关文章

斜率优化系列——训练记录

斜率优化训练记录 前言 斜率优化一般用于优化dp的转移,借着训练斜率优化的相关问题来提升一些DP思维.选择老学长留下的专题场来练手,由于该场题数较多,以及个人不太愿意长时间进行单一专题训练,因此开此文来记录断续的训练结果和心得. 记录 题一 由一道简单入门题玩具装箱开头,题意和思路比较简单就不讲了. 代码 #include<bits/stdc++.h> #define dd(x) cout<<#x<<" = "<<x<<&qu

NOI前训练记录

从今年年初开始就没怎么碰oi,学了三个月文化课,然后就是省选到处跑(浪),进了省队后又去北京打(浪)了波(七)铁(天),回家后又生了一星期病,感觉自己noi凉透了... ctsc因为运气的原因有人放弃D3自己才拿到au,apio什么牌都没拿到,自己这么菜的主要原因可能还是没怎么做题吧,五个月不碰oi,已经连dfs都不会了,还有两个月就noi了,再不训练又要为JS丢脸了,自己拿不到au却占了个省队名额,而阿老师邀请赛冠军的水平却没进省队,感觉自己不珍惜这个省队名额真的是说不过去 本文就记录一下本人

Dailight 训练记录

现场赛记录 19 CCPC 湘潭邀请赛  11/Gold 19 ICPC 西安邀请赛 49/Silver 训练规划: hl: 1.深入增强图论,数据结构的能力,包括但不限于树形dp,点分治,多写dp,学习斜率优化,四边形优化 2.保证银牌及以下图论,数据结构,dp的通过率,最好可以在十分钟内出思路 3.养成提交前检查代码的习惯,不出现傻逼错误. 4.学习简单数论(逆元,组合数),尤其是数论结合图论的应用 gbs: 1.加快上机 ->  写完代码过样例 这一过程的速度. 2.减少debug占用机时

二分暑假专题 训练记录 2017-7-29

POJ3258-River Hopscotch 题意: 给你区间[0,L]给你n个石头,然后去除m个石头  最大化 石头间最小的距离 思路: 首先0和L 这两个石头是不可以动的   然后用 s 数组记录 整个区间的石头 然后排序  此时石头的排序就是有序的了  然后二分套模板 接着check函数才是最关键的好的把 从0到 n+1-m   总共就有 n+2-m 个石头了 而由于第0个石头不可以动 , 所以从第一个开始动 同时判断条件是 s[cur] - s[last] < d 而不是 <= #i

dp暑假专题 训练记录

A 回文串的最小划分 题意:给出长度不超过1000的字符串,把它分割成若干个回文字串,求能分成的最少字串数. #include <iostream> #include <cstdio> #include <string.h> #include <string> using namespace std; const int mod = 1e9 + 7; const int maxn = 1000 + 5; const int INF = 0x3f3f3f3f;

训练记录PART1

11/05 bestcoder #93 C 等价于给出很多环,等概率选择N个点,收益为出现过点的环的环长lcm.不同的环只有 \(\sqrt {26}=6\) 个,用\(f_S\)表示点出现在状态为S的那些环里的选取总数,DP一下即可. bestcoder #93 D 考虑meet in the middle.推一下式子,设左侧选的数和为\(A_{left}t\),两两乘积之和为\(B_{left}\),那么满足\(B_{left}+B_{right}+A_{left}*A_{right}>=0

20160813下午训练记录

*下午听说讲课很简单,被拉去隔壁做只可口胡 不可写的题了 T1 江苏省选的时候有道题面差不多的题目,邵战狂当时跟我口胡过这题 我们还是先不考虑1 那么我们选取一个元素,当加入第二个的时候,两个的奇偶性不同,加入第三个数时,肯定不满足. 那么我们特判一下1的数目,然后乱搞一下 int n,a[1234]; bool np[33333333]; int tot,pr[8001234]; const int N=30000000; void sieve(){ for(int i=2;i<=N;i++)

20160819训练记录

T1 给定一个序列 ,在第i时刻位置左边插入一个数i 求最后的序列 [题解]倒着做..插入的位置是左边有空格的位置 用线段树维护一下单点修改 线段树写的优雅一点 #include<cstdio> #include<iostream> #include<algorithm> using namespace std; int p,f[4444444],g[4444444],ans[4444444]; int find(int i,int l,int r,int x){ f[

20160818训练记录

T1 "开心题" 每个点如果不是根节点,子树个数等于度数减一.然后随便算一算 T2 数据范围   首先对于两个长度相等的偶数串.把他两两分组 1 2 3 4 5 6 7 8 考虑一个和8相等的(包括交换内部后)的块 先把他调到头部然后调到尾部.然后删除这一块 然后发现这样的可以对每个串求出字典序最小的等价表达..其实随便计算一下就解决了 #include<cstdio> #include<string.h> #include<iostream> #i