day1训练(省赛前)

考完期中考试的弱鸡补题恢复状态ing.

416div2A.

(水题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <bits/stdc++.h>
#define ll long long
#define s second
#define f first
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=1e5+10;
using namespace std;
int main(){
    ll n,m;cin>>n>>m;
    int cnt1=0;int t=1e5;
    inc(i,1,t){
        if(m<1ll*i*(i+1)){
            cnt1=i-1;break;
        }
    }
    int cnt2=0;
    inc(i,1,t){
        if(n<1ll*i*i){
            cnt2=i-1;break;
        }
    }
    //cout<<cnt1<<" "<<cnt2<<endl;
    if(cnt1>=cnt2) cout<<"Vladik"<<endl;
    else cout<<"Valera"<<endl;
    return 0;
}

 416div2B.(水题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <bits/stdc++.h>
#define ll long long
#define s second
#define f first
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=1e4+10;
using namespace std;
int a[MAXN];
int main(){
    int n,m;cin>>n>>m;
    inc(i,1,n) cin>>a[i];
    int l,r,x;int cnt,cnt1;
    inc(i,1,m){
        cin>>l>>r>>x;
        if(x<l||x>r){
            cout<<"Yes"<<endl;continue;
        }
        int t1=x-l+1;cnt=cnt1=0;
        inc(j,l,r){
            if(a[j]<a[x]) cnt++;
            if(a[j]==a[x]) cnt1++;
        }
        if(cnt+cnt1>=t1&&cnt<t1) puts("Yes");
        else puts("No");
    }
    return 0;
}

 416div2E

题意:http://codeforces.com/contest/811/problem/E

题解:考虑到线段树维护并查集,难点在如何维护合并,考虑到每次合并只需要最左边的一列和最右边的一列 所以我们考虑将左儿子的两端的两列和右儿子两端的两列映射到数组中 然后用并查集维护合并区间的连通性 查询即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <bits/stdc++.h>
#define ll long long
#define s second
#define f first
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=1e5+10;
using namespace std;
ll read(){ 
    ll x=0,f=1;char ch=getchar(); 
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 
    return f*x; 
}
int n,m,q,cnt;
int G[11][MAXN],vis[MAXN*10],fa[44];
int a[5];
typedef struct node{
    int l,r,ans;
    int L[11],R[11];
}node;
node d[MAXN<<2];
int find1(int x){
    if(x==fa[x]) return x;
    else return fa[x]=find1(fa[x]);
}
node merge(node x,node y){
    node z;z.ans=x.ans+y.ans;
    inc(i,1,n){
        if(vis[x.L[i]]) fa[i]=vis[x.L[i]];
        else vis[x.L[i]]=i,fa[i]=i;
    }
    inc(i,1,n){
        if(vis[x.R[i]]) fa[i+n]=vis[x.R[i]];
        else vis[x.R[i]]=n+i,fa[i+n]=n+i;      
    }
    inc(i,1,n){
        if(vis[y.L[i]]) fa[i+2*n]=vis[y.L[i]];
        else vis[y.L[i]]=i+2*n,fa[i+2*n]=i+2*n;
    }
    inc(i,1,n){
        if(vis[y.R[i]]) fa[i+3*n]=vis[y.R[i]];
        else vis[y.R[i]]=i+3*n,fa[i+3*n]=i+3*n;
    }
    a[1]=x.l;a[2]=x.r;a[3]=y.l;a[4]=y.r;
    inc(i,1,n){
        if(G[i][x.r]!=G[i][y.l]) continue;
        int t1=find1(n+i);
        int t2=find1(n*2+i);
        if(t1==t2) continue;
        if(t1>t2) swap(t1,t2);
        z.ans--;
        fa[t2]=t1;
    }
    inc(i,1,n) z.L[i]=(find1(i)-1)*m+x.l;
    inc(i,1,n){
        int t1=find1(3*n+i);int t2=(t1-1)/n+1;int t3=(t1-1)%n+1;
        z.R[i]=(t3-1)*m+a[t2];
    }
    inc(i,1,n) vis[x.R[i]]=vis[x.L[i]]=vis[y.L[i]]=vis[y.R[i]]=0;
    z.l=x.l;z.r=y.r;
    return z;
}
void built(int rt,int l,int r){
    if(l==r){
        d[rt].l=d[rt].r=l;
        d[rt].L[1]=d[rt].R[1]=l;d[rt].ans++;
        inc(i,2,n){
            if(G[i][l]==G[i-1][l]) d[rt].L[i]=d[rt].R[i]=d[rt].L[i-1];
            else d[rt].L[i]=d[rt].R[i]=(i-1)*m+l,d[rt].ans++;
        }
        return ;
    }
    int mid=(l+r)>>1;
    built(rt<<1,l,mid);
    built(rt<<1|1,mid+1,r);
    d[rt]=merge(d[rt<<1],d[rt<<1|1]);
}
bool flag;node ttt;
void querty(int rt,int ql,int qr){
    if(ql<=d[rt].l&&d[rt].r<=qr){
        if(!flag) ttt=d[rt],flag=1;
        else ttt=merge(ttt,d[rt]);
        return ;
    }
    int mid=(d[rt].l+d[rt].r)>>1;
    if(ql<=mid) querty(rt<<1,ql,qr);
    if(qr>mid) querty(rt<<1|1,ql,qr);
}
int main(){
    n=read();m=read();q=read();
    inc(i,1,n){
        inc(j,1,m) G[i][j]=read();
    }
    built(1,1,m);
    int l,r;
    inc(i,1,q){
        l=read();r=read();
        flag=0;querty(1,l,r);
        printf("%d\n",ttt.ans);
    }
    return 0;
}

480div2E

题意:http://codeforces.com/contest/980/problem/E

题解:考虑到数越大对答案的贡献越大 我们可以从大往小考虑 对于每个点 我们来考虑是否应该删除(及这个点目前的深度加上已经保留点的个数是否小于n-k来判断删除的必要性 为什么这么做?可以仔细推一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <bits/stdc++.h>
#define ll long long
#define s second
#define f first
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=1e6+10;
using namespace std;
ll read(){ 
    ll x=0,f=1;char ch=getchar(); 
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 
    return f*x;    
}
 
int n,k;
vector<int>vec[MAXN];
vector<int>vv;
int d[MAXN<<2],flag[MAXN<<2],dep[MAXN],p[MAXN],fp[MAXN],cnt,num[MAXN],fa[MAXN];
bool vis[MAXN];
void dfs(int v,int pre,int deep){
    p[v]=++cnt;fp[cnt]=v;dep[v]=deep+1;num[v]=1;
    fa[v]=pre;
    for(int i=0;i<vec[v].size();i++){
        int u=vec[v][i];
        if(u!=pre){
            dfs(u,v,deep+1);
            num[v]+=num[u];
        }
    }
}
void push(int x){
    if(flag[x]){
        flag[x<<1]+=flag[x];
        flag[x<<1|1]+=flag[x];
        d[x<<1]+=flag[x];
        d[x<<1|1]+=flag[x];
        flag[x]=0;
    }
}
void built(int rt,int l,int r){
    if(l==r){
        d[rt]=dep[fp[l]];flag[l]=0;return ;
    }
    int mid=(l+r)>>1;
    built(rt<<1,l,mid);
    built(rt<<1|1,mid+1,r);
}
void update(int rt,int l,int r,int ql,int qr,int vul){
    if(ql<=l&&r<=qr){
        d[rt]+=vul;flag[rt]+=vul;return ;
    }
    int mid=(l+r)>>1;
    push(rt);
    if(ql<=mid) update(rt<<1,l,mid,ql,qr,vul);
    if(qr>mid) update(rt<<1|1,mid+1,r,ql,qr,vul);
}
int querty(int rt,int l,int r,int t){
    if(l==r) return d[rt];
    int mid=(l+r)>>1;
    push(rt);
    if(t<=mid) querty(rt<<1,l,mid,t);
    else querty(rt<<1|1,mid+1,r,t);
}
int main(){
    n=read();k=read();int u,v;
    inc(i,1,n-1){
        u=read();v=read();
        vec[u].push_back(v);
        vec[v].push_back(u);
    }
    dfs(n,0,0);
    built(1,1,n);
    int cnt1=0;
    for(int i=n;i>=1;i--){
        if(vis[i]) continue;
        int t1=querty(1,1,n,p[i]);
        if(t1+cnt1<=n-k){
            for(int j=i;(vis[j]==0)&&(j!=0);j=fa[j]) update(1,1,n,p[j],p[j]+num[j]-1,-1),vis[j]=1,cnt1++;
        }
        else vv.push_back(i);
    }
    sort(vv.begin(),vv.end());
    for(int i=0;i<vv.size();i++) printf("%d ",vv[i]);
    printf("\n");
    return 0;
}

  

posted @   wang9897  阅读(139)  评论(0编辑  收藏  举报
编辑推荐:
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
阅读排行:
· C# 13 中的新增功能实操
· Ollama本地部署大模型总结
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(4)
· langchain0.3教程:从0到1打造一个智能聊天机器人
· 2025成都.NET开发者Connect圆满结束
点击右上角即可分享
微信分享提示