Achen毒瘤模拟题T1——数数(counting)

题目大意:给出一个区间,并给定应两两相等的数位的数对,求满足的数的个数。

范围:1e5

做法:

先用并查集,将互相相等的树连成一块,统计块的个数,从高位到低位扫描,然后容斥即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<queue>
#include<ctime>
#define MAXN 200005
#define ll long long
#define maxn 15
#define maxs 1000005
#define inf 1e9
#define eps 1e-9
using namespace std;
inline char gc() {
    static char now[1<<16],*S,*T;
    if (T==S) {
        T=(S=now)+fread(now,1,1<<16,stdin);
        if (T==S) return EOF;
    }
    return *S++;
}
inline ll readlong() {
    ll x=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘) {
        if(ch==‘-‘)f=-1;
        ch=getchar();
    }
    while(ch>=‘0‘&&ch<=‘9‘) {
        x*=10;
        x+=ch-‘0‘;
        ch=getchar();
    }
    return x*f;
}
inline int read() {
    int x=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘) {
        if(ch==‘-‘)f=-1;
        ch=getchar();
    }
    while(ch>=‘0‘&&ch<=‘9‘) {
        x*=10;
        x+=ch-‘0‘;
        ch=getchar();
    }
    return x*f;
}
void putint(long long t) {
    int ans[40]= {0};
    for(; t; t/=10)ans[++ans[0]]=t%10;
    for(; ans[0]; ans[0]--)putchar(‘0‘+ans[ans[0]]);
    putchar(‘\n‘);
}
const int mod=19260817;
const int N=100005;
int n,q;
int L[N],R[N];
int fa[N];
int getf(int x){
    if(fa[x]==x){
        return x;
    }
    return fa[x]=getf(fa[x]);
}
int ksm(int x,int k){
    int ret=1;
    int ans=x%mod;
    while(k){
        if(k&1){
            ret=ret*ans%mod;
        }
        ans=ans*ans%mod;
        k>>=1;
    }
    return ret;
}
int dfs(int a[]){//实则是求从0算至a[]这一区间的个数
    int tot=0;
    for(int i=1;i<=n;i++){
        if(fa[i]==i){
            tot++;
        }
    }
//    cout<<"tot="<<tot<<endl;
    int ans=0;
    for(int i=n;i>0;i--){
        if(fa[i]==i){
            tot--;
            ans=(ans+a[i]*ksm(10,tot))%mod;
        }
        if(a[getf(i)]<a[i]){
            ans=(ans+ksm(10,tot))%mod;
        }
        if(a[getf(i)]!=a[i]){
            break;
        }
    }
    return ans;
}
int main(){
    n=read();
    for(int i=1;i<=n;i++){
        fa[i]=i;
    }
    for(int i=1;i<=n;i++){
        L[i]=read();
    }
    for(int i=1;i<=n;i++){
        R[i]=read();
    }
    q=read();
    while(q--){
        int x=read();
        int y=read();
        x=getf(x);
        y=getf(y);
        fa[min(x,y)]=max(x,y);
//        cout<<"fa["<<min(x,y)<<"]"<<"= "<<max(x,y);
    }

//    cout<<dfs(R)<<" "<<dfs(L)<<endl;

    cout<<(dfs(R)+mod-dfs(L))%mod;

    return 0;
}

原文地址:https://www.cnblogs.com/LHbz/p/9721004.html

时间: 2024-08-01 17:10:04

Achen毒瘤模拟题T1——数数(counting)的相关文章

CCF模拟题 有趣的数

有趣的数 时间限制: 1.0s 内存限制: 256.0MB 问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高位数字不为0. 因此,符合我们定义的最小的有趣的数是2013.除此以外,4位的有趣的数还有两个:2031和2301. 请计算恰好有n位的有趣的数的个数.由于答案可能非常大,只需要输出答案除以1000000007的余数. 输入格式 输入只有一

20171108 模拟题 T1

T1 为什么要写这个题呢? 我只是想说:链表也能做!! QAQAQ 可是……细节什么的考场写的好晕…… (其实我不想解释代码了QAQAQ Codes: #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; const int N = 100000 + 10; char s[N]; int ans,ans1,ans2; int

金色十月线上编程比赛第一题:小女孩数数

一个小女孩正在用左手手指数数,从1数到n.她从拇指算作1开始数起,然后,食指为2,中指为3,无名指为4,小指为5.接下来调转方向,无名指算作6,中指为7,食指为8,大拇指为9,如此反复.问最后会停在那个手指上?用编号1.2.3.4.5依次表示大拇指.食指.中指.无名指.小指. 输入格式: 输入多组数据.每组数据占一行,只包含一个整数n(1<=n<=1000000000). 输出格式: 每组数据占一行,只包含一个介于1和5之间的整数,表示最后停留的手指. 答题说明: 输入样例: 1 10 100

一天一道算法题---6.11---大数阶乘

感谢微信平台----一天一道算法题----每天多一点进步 大数的概念 感觉是我接触acm 1 2 个月之后才有的....64位的Long long 和 __int64 也大概都是那时候才有的.. 大数 相加 相乘 相除 求余  相减不知道 有没有... 都是应该要掌握的.. 可能 我也会陆续把上面的全慢慢贴上来 // 呆会就直接把 微信提供的代码给贴上来了  先要去次午饭了 早饭 午饭永远是连一起的 .......... // 刚刚碰到个最小生成树的题 第一次用了邻接表去做 蛮cool == 一

CSDN挑战编程——《金色十月线上编程比赛第一题:小女孩数数》

金色十月线上编程比赛第一题:小女孩数数 题目详情: [金色十月线上编程比赛规则] 一个小女孩正在用左手手指数数,从1数到n.她从拇指算作1开始数起,然后,食指为2,中指为3,无名指为4,小指为5.接下来调转方向,无名指算作6,中指为7,食指为8,大拇指为9,如此反复.问最后会停在那个手指上?用编号1.2.3.4.5依次表示大拇指.食指.中指.无名指.小指. 输入格式: 输入多组数据.每组数据占一行,只包含一个整数n(1<=n<=1000000000). 输出格式: 每组数据占一行,只包含一个介

noip模拟题题解集

最近做模拟题看到一些好的题及题解. 升格思想: 核电站问题 一个核电站有N个放核物质的坑,坑排列在一条直线上.如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质. 任务:对于给定的N和M,求不发生爆炸的放置核物质的方案总数 输入:输入文件只一行,两个正整数N,M( 1<N<50,2≤M≤5) 输出:输出文件只有一个正整数S,表示方案总数. 运用升格思想.设N个坑不会发生爆炸的方案数是f[N],那么我们假设N以前的坑的方案 都已知了,那么我们只需要考虑第N个坑如何放即可(顺

POJ 模拟题集合

http://www.cppblog.com/Uriel/articles/101592.html 感觉这个暑假没有去年有激情啊,,,还没到状态就已经块上学了,,, 真是弱暴了,,,找几道模拟题刷刷... 标加号表示已AC... + 1008   历法,不难 + 1102   不难. + 1028   纯模拟.被题目坑了一下.. 1023   貌似搞了一会儿.. 1051   算是模拟,写得比较麻烦,要细心 1099   跟化学式有关的模拟,有意思,高兴的是这题完全是自己想的AC的.. 1107

一道模拟题

问题:把英文单词表示的数字转换为阿拉伯数字,要求数字不超过整形范围,数字形如abc,def,hrg. 第一行表示有几组数据,第二行输入英文. 输出:相应的阿拉伯数字. 例如:input: 3 eleven one hundred and two output: 11 102 分析:要注意百万和千要断位,还有要从高位往低位查找,注意分情况讨论. 1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 st

XJOI 郎思轲模拟题

今天比赛的是郎思轲出的模拟题,比较偏数学. 全国青少年奥林匹克联赛 CCF-NOIP 2017模拟试题 提高组(复赛)day1 竞赛时间:210分钟 命题:郎思轲 题目一览: 题目名称 不定长数组 台球游戏 对称的多项式 题目类型 传统型 传统型 传统型 目录 vector billiards poly 可执行文件名 vector billiards poly 输入文件名 vector.in billiards.in poly.in 输出文件名 vector.out billiards.out