Skip to content

泉州一中信息学Blog

信息学奥赛技术分享博客

  • 登录
  • 小学oj
  • 中学oj
  • 测试页面1
  • Toggle search form

NaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN Day6

Posted on 2024年11月15日2024年11月15日 By 陈麒润 NaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN Day6无评论

今日看点

$\texttt{集训training 结束end 大家everyone 变硬hard}$

$\texttt{集训training 结束end 大家everyone 原神genshin}$

$\texttt{“T2 std怎么超时了,抓一个小朋友来当标程”}$

$\texttt{“T3 90分是怎么做到的”}$

$\texttt{“T3 输出-1?”}$

$\texttt{《睡一觉起来网好了》}$

$\texttt{《两个机房共用十兆带宽》}$

$\texttt{《2v5 优势在我》}$

$\texttt{《牛腩煲但是没吃牛肉》}$

A

根据每个数位有没有给他压成 [0,2^{10}) 的二进制数,第 i 位代表有没有 i。

然后一个数要算有相交的可以算没有相交的。

然后开个高位前缀和就可以了。

#include
#define CKE if(CHECK)
#define FRE if(FIL)
#define int long long
#define MX 1000005
using namespace std;
const int CHECK=0,FIL=1;int read();
int n,a,p[MX],w[1024];
signed main(){
    //ios::sync_with_stdio(false);
    //cin.tie(0);cout.tie(0);
    FRE freopen("training.in","r",stdin);
    FRE freopen("training.out","w",stdout);
    n=read();
    for(int i=1;i<=n;i++){
        a=read();
        while(a){
            p[i]|=(1<<(a%10));
            a/=10;
        }w[p[i]]++;
    }
    for(int i=0;i<10;i++){
        for(int j=0;j<1024;j++){
            if(j&(1<<i)){
                w[j]+=w[j^(1<<i)];
            }
        }
    }
    a=n*(n-1);
    for(int i=1;i<=n;i++){
        a-=w[1023^p[i]];}
    printf("%lld\n",a/2);
    return 0;
}
int read(){
    int Ca=0;char Cr=' ';int Cf=1;
    while(Cr'9'){Cr=getchar();if(Cr=='-'){Cf=-1;}}
    while(Cr>='0' && Cr<='9'){Ca=Ca*10+Cr-48;Cr=getchar();}
    return Ca*Cf;
}

B

std 你怎么超时了哈哈哈哈哈哈

人话:选子图,最大化最小度数。

一个状态想让答案变大肯定要删除度数最小的点。

线段树,支持单点修改,全局最小值,查找最小位置。

#include
#define CKE if(CHECK)
#define FRE if(FIL)
#define MX 100005
using namespace std;
const int CHECK=0,FIL=1;int read();
int n,m,res,d[MX],hs[MX];
vector v[MX];
class SegmentTree{
    public:
    int tr[MX*4];
    void set(int t,int w){tr[t]=w;}
    void Set(int t,int l,int r,int L,int w){
        if(l>=r){set(t,w);return;}
        int mid=(l+r)>>1;
        if(L<=mid) Set(t<<1,l,mid,L,w);
        else Set(t<<1|1,mid+1,r,L,w);
        tr[t]=min(tr[t<<1],tr[t<=r) return l;
        int mid=(l+r)>>1;
        if(tr[t<<1]<tr[t<<1|1]) return Find(t<<1,l,mid);
        else return Find(t<<1|1,mid+1,r);
    }
}A;
signed main(){
    //ios::sync_with_stdio(false);
    //cin.tie(0);cout.tie(0);
    FRE freopen("end.in","r",stdin);
    FRE freopen("end.out","w",stdout);
    n=read();m=read();
    while(m--){
        int a=read();int b=read();
        v[a].push_back(b);d[b]++;
        v[b].push_back(a);d[a]++;
    }
    for(int i=1;i<=n;i++) A.Set(1,1,n,i,d[i]);
    res=A.tr[1];
    for(int i=1;i<n;i++){
        int t=A.Find(1,1,n);hs[t]=1;
        //cout<<t<<' ';
        A.Set(1,1,n,t,1919810);
        for(auto j:v[t]){
            if(!hs[j]){
                A.Set(1,1,n,j,--d[j]);}}
        res=max(res,A.tr[1]);
        //cout<<A.tr[1]<<'\n';
    }printf("%d\n",res);
    return 0;
}
int read(){
    int Ca=0;char Cr=' ';int Cf=1;
    while(Cr'9'){Cr=getchar();if(Cr=='-'){Cf=-1;}}
    while(Cr>='0' && Cr<='9'){Ca=Ca*10+Cr-48;Cr=getchar();}
    return Ca*Cf;
}

C

lxl:“90 分是怎么做到的”
lxl:“输出 -1?”

我是双 \log 爆草大神。

容易知道一定有一种编号方案使得任何时刻任意连通块编号连续。

所以操作一开并查集,操作二区间加。

操作三答案是 a现在的权值 减去 a合并前的权值。

那么怎么知道合并前的权值呢?

整!体!二!分!

不知道为啥有一个点输出-1,和 0 取 \max 就过了。

超绝 130 行代码。

#include
#define CKE if(CHECK)
#define FRE if(FIL)
#define MX 300005 
#define GP pair
#define MP make_pair
using namespace std;
const int CHECK=0,FIL=1;int read();
int n,fd[MX],nw[MX];
unordered_map mp[MX];
int l[MX],r[MX],f[MX],res[MX];
int find(int i){return f[i]=(f[i]==i)?i:find(f[i]);}
//fa on tree
//f on bcj
int q,que[MX][3];
int RES[MX],X[MX],Y[MX],hcnt;
GP quer[MX];
vector v[MX];
class Tree{public:
    int o[MX];
    void add(int a,int b){while(a<=n){o[a]+=b;a+=(a&-a);}}
    int sum(int a){int b=0;while(a){b+=o[a];a-=(a&-a);}return b;} 
}A;
void dfs(int t){
    fd[t]=1;
    sort(v[t].begin(),v[t].end());
    for(auto I:v[t]){
        dfs(I.second);
    }nw[t]=++hcnt;
}
void merge(int a,int b){
    a=find(a),b=find(b);
    l[a]=min(l[a],l[b]);
    r[a]=max(r[a],r[b]);
    f[b]=a;
}
signed main(){
    //ios::sync_with_stdio(false);
    //cin.tie(0);cout.tie(0);
    FRE freopen("everyone.in","r",stdin);
    FRE freopen("everyone.out","w",stdout);
    n=read();q=read();
    for(int i=1;i<=n;i++) f[i]=i;
    for(int i=1;i<=q;i++){
        int a=0,b=0;
        que[i][0]=read();
        a=que[i][1]=read();
        if(que[i][0]!=2){
            b=que[i][2]=read();}
        if(que[i][0]==1){
            a=find(a);b=find(b);
            if(a==b) continue;
            //swap(a,b);
            v[b].push_back(MP(-i,a)); 
            f[a]=b;
            //cout<<a<<' '<<b<<'\n';
        } 
    }
    //return 0;
    //编号
    for(int i=1;i<=n;i++){
        if(!fd[i]) dfs(find(i));
    }hcnt=0;
    //return 0;
    //
    for(int i=1;i<=n;i++){
        l[i]=r[i]=nw[i];
        f[i]=i;
        //cout<<i<"<<nw[i]<<'\n';
    }
    for(int i=1;i<=q;i++){
        int op=que[i][0];
        int a=que[i][1];
        int b=que[i][2];
        if(op==1){
            merge(a,b);
            mp[a][b]++;
            mp[b][a]++;
        }else if(op==2){
            a=find(a);
            //cout<<l[a]<<' '<<r[a]<<'\n';
            A.add(l[a],1);
            A.add(r[a]+1,-1);
        }else{
            if(find(a)!=find(b)){continue;}
            res[i]=A.sum(nw[a])+mp[a][b];
            hcnt++,X[i]=1,Y[i]=i,RES[i]=0;
            //cout<<i<<" init "<<res[i]<>1,i);
        }
        if(!hcnt) break;
        sort(quer+1,quer+1+hcnt);
        int pl=1;
        for(int i=1;i<=n;i++){
            l[i]=r[i]=nw[i];
            f[i]=i;A.o[i]=0;
        }
        for(int i=1;i<=q;i++){
            int op=que[i][0];
            int a=que[i][1];
            int b=que[i][2];
            if(op==1){
                merge(a,b);
            }else if(op==2){
                a=find(a);
                A.add(l[a],1);
                A.add(r[a]+1,-1);
            }
            while(pl<=hcnt && quer[pl].first<=i){
                int T=quer[pl].first;
                int id=quer[pl++].second;
                a=que[id][1],b=que[id][2];
                if(find(a)==find(b)){
                    Y[id]=T-1;//cout<<id<<" tryWA "<<Y[id]<<'\n';
                }else{
                    X[id]=T+1;//cout<<id<<" tryAC "<<X[id]<='0' && Cr<='9'){Ca=Ca*10+Cr-48;Cr=getchar();}
    return Ca*Cf;
}

D

赛时没想出来,大悲。

把 m+q 个区间按左端点排序,从右往左扫。

扫到查询区间的时候计算答案。

这样的好处是选取的线段不会从左侧超出去。

$f_i$ 表示包含位置 $i$ 的区间的最小右端点(没有则为 $\infin$)。

那么扫到一个区间的时候可以合并的充要条件是 \forall i\in[l,r],f_i\leq r。

所以维护 f,支持区间取最小值和区间求最大值,是容易的。

#include
#define CKE if(CHECK)
#define FRE if(FIL)
#define MX 500005
#define MT make_tuple
#define GT tuple
using namespace std;
const int CHECK=0,FIL=1;int read();
int n,m,q,x,y,k,res[MX];GT ww[MX*2];
class SegmentTree{public:
    int tr[MX*4],lz[MX*4];
    void set(int t,int w){
        tr[t]=min(tr[t],w);
        if(!lz[t]) lz[t]=w;
        else lz[t]=min(lz[t],w);
    }
    void pd(int t){
        if(!lz[t]) return;
        set(t<<1,lz[t]);
        set(t<=r) return;
        int mid=(l+r)>>1;
        build(t<<1,l,mid);
        build(t<<1|1,mid+1,r);
    }
    void Set(int t,int l,int r,int L,int R,int w){
        if(L<=l && r>1;pd(t);
        if(L<=mid) Set(t<mid) Set(t<<1|1,mid+1,r,L,R,w);
        tr[t]=max(tr[t<<1],tr[t<<1|1]);
    }
    int Max(int t,int l,int r,int L,int R){
        if(L<=l && r>1,ans=0;pd(t);
        if(L<=mid) ans=max(ans,Max(t<mid) ans=max(ans,Max(t<<1|1,mid+1,r,L,R));
        return ans;
    }
}A; 
signed main(){
    //ios::sync_with_stdio(false);
    //cin.tie(0);cout.tie(0);
    FRE freopen("hard.in","r",stdin);
    FRE freopen("hard.out","w",stdout);
    n=read();m=read();q=read();
    A.build(1,1,n);
    for(int i=1;i<=m;i++){
        x=read();y=read();
        ww[++k]=MT(x,0,y);
    }
    for(int i=1;i=1;i--){
        x=get(ww[i]),y=get(ww[i]);
        int id=-get(ww[i]);
        //cout<<x<<' '<<y<<' '<<id<<'\n';
        if(id){
            res[id]=(A.Max(1,1,n,x,y)<=y);
        }else{
            A.Set(1,1,n,x,y,y);
        }
    }
    for(int i=1;i<=q;i++) printf(res[i]?"YES\n":"NO\n");
    return 0;
}
int read(){
    int Ca=0;char Cr=' ';int Cf=1;
    while(Cr'9'){Cr=getchar();if(Cr=='-'){Cf=-1;}}
    while(Cr>='0' && Cr<='9'){Ca=Ca*10+Cr-48;Cr=getchar();}
    return Ca*Cf;
}
训练日志

文章导航

Previous Post: NAN.NAN.NAN DAY 5
Next Post: NANAN DAY 6

发表回复 取消回复

要发表评论,您必须先登录。

2025年 6月
一 二 三 四 五 六 日
 1
2345678
9101112131415
16171819202122
23242526272829
30  
« 2月    

2024常州 Class Classic OI Problems Contest cqr的长乐集训2023 CZYZ LOC New Game NOI NOIP Password Protected PM_PK Preview Problems Retrospect Selfmade Qusetion STL The end Training Uneasy Problem 蒟蒻 通报

  • 训练日志
  • 链表
  • 入门
  • 模拟
  • dfs序
  • 并查集
  • spfa
  • 最小割
  • 矩阵树定理
  • 仙人掌
  • BSGS
  • 凸包
  • 回文自动机
  • 递推与动归
  • 堆
  • 莫队算法
  • ST表
  • Treap
  • 树套树
  • 可持久化线段树
  • 初赛
  • 搜索
  • 贪心
  • 深度优先搜索
  • 欧拉图
  • dijkstra
  • 费用流
  • 哈夫曼树
  • kruskual
  • 置换
  • 旋转卡壳
  • KMP
  • 区间动归
  • STL
  • 链表
  • 可并堆
  • sply
  • 主席树
  • 可持久化字典树
  • 算法
  • 动态规划
  • 构造
  • 广度优先搜索
  • 最短路
  • floyd
  • 最大流
  • 虚树
  • prim
  • 筛法
  • 半平面交
  • 字典树
  • 背包动归
  • 基础数据结构
  • 分块
  • 线段树
  • 替罪羊树
  • K-DTree
  • 图论
  • 二分法
  • 迭代搜索
  • 拓扑排序
  • 有上下界网络流
  • 生成树
  • 快速幂
  • 后缀数组
  • 树形动归
  • 哈希表
  • 中级数据结构
  • 平衡树
  • 可持久化数据结构
  • 数据结构
  • 三分法
  • 启发式搜索
  • 图的连通
  • 点分治
  • 博弈论
  • AC自动机
  • 状压动归
  • 单调栈
  • 树状数组
  • 高级数据结构
  • OI资料
  • 数学
  • 高精度
  • 差分约束
  • 树上倍增
  • 素数测试
  • 后缀自动机
  • 数位动归
  • 单调队列
  • 新闻
  • 几何
  • 随机化
  • 二分图染色
  • 树链剖分
  • 欧拉函数
  • manacher
  • 斜率优化
  • 离线处理
  • 信息学奥赛学长风采
  • 字符串
  • 二分图匹配
  • prufer编码
  • 卡特兰数
  • 密码学
  • 决策单调
  • 赛后总结
  • 其他
  • 2-SAT
  • 最近公共祖先
  • 矩阵乘法
  • 记忆化搜索
  • 网络流
  • Link cut tree
  • 排列组合
  • 树
  • 高斯消元
  • 乘法逆元
  • 容斥原理
  • 调和级数
  • 概率与期望
  • 模线性方程组
  • 莫比乌斯反演
  • 快速傅里叶变换
  • 扩展欧几里德
  • 最大公约数与最小公倍数

近期文章

  • DP杂题
  • 2025年2月13日模拟赛
  • HLOJ-TEST ROUND 4-T1/T2(构造)- 3
  • HLOJ-TEST ROUND 4-T1/T2(构造)- 2
  • HLOJ-TEST ROUND 4-T1/T2(构造)- 1

近期评论

归档

  • 2025年2月
  • 2025年1月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年3月
  • 2024年2月
  • 2024年1月
  • 2023年12月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月

Copyright © 2025 泉州一中信息学Blog.

Powered by PressBook WordPress theme