这是题目描述的链接: http://lifecraft-mc.com/wp-content/uploads/2018/03/problems1.pdf

(虽然这次没去清北,但还是厚颜无耻的做了一下这套题)

T1:

估计noip水平的选手都知道这个题可以用矩阵乘法水过去,但是作为一个还有8天就要省选的蒟蒻,我来提供一种娱乐做法:指数型生成函数。 像1和3这样必须出现且出现偶数次的数就可以用一个闭形式为 (e^x + e^-x)/2 - 1 的指数型生成函数表示,具体的推式子见代码。

/*
ANS = (e^x)^3 * ((e^x + e^-x)/2 -1)^2
= e^3x * ((e^2x + 2 + e^-2x)/4 - (e^x + e^-x) + 1)
= (e^5x + e^x + 2*e^3x)/4 - (e^4x + e^2x) +e^3x
= (5^x + 2*3^x + 1)/4 - (4^x + 2^x) + 3^x
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<vector>
#include<cstdlib>
#define ll long long
using namespace std;
const int ha=1000000007;
const int inv=ha/2+1;
int ans=0;
ll n; inline int add(int x,int y){
x+=y;
return x>=ha?x-ha:x;
} inline int DOUBLE(int x){
return add(x,x);
} inline int ksm(int x,int y){
int an=1;
for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
return an;
} int main(){
// freopen("number.in","r",stdin);
// freopen("number.out","w",stdout);
scanf("%lld",&n),n%=(ha-1);
ans=add(add(ksm(5,n),1),DOUBLE(ksm(3,n)));
ans=ans*(ll)inv%ha*(ll)inv%ha;
ans=add(ans,ha-add(ksm(2,n),ksm(4,n)));
ans=add(ans,ksm(3,n));
printf("%d\n",ans);
return 0;
}

  

T2:

这也是一道比较基础的组合计数了2333,首先当我们确定多少行被选了奇数次的时候,多少列被选奇数次也就确定了(除了被选奇数次的行数*2==n 这种特殊情况),所以我们可以直接大力枚举选了多少奇行,然后乘上一些组合系数即可。

/*
设最后有x行y列被选了奇数次,那么满足:
x*m + (n-2x)*y =k
并且 (r-x) 和 (c-y) 都必须是偶数。 然后此时的方案数就是:
C(n,x) * C(m,y) * C(n+(r-x)/2-1,(r-x)/2) * C(m+(c-y)/2-1,(c-y)/2)
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<vector>
#include<cstdlib>
#define ll long long
using namespace std;
const int ha=1000000007;
const int maxn=300000;
int n,m,r,c,ans=0;
int jc[maxn+5],ni[maxn+5];
ll K; inline int add(int x,int y){
x+=y;
return x>=ha?x-ha:x;
} inline int ksm(int x,int y){
int an=1;
for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
return an;
} inline void init(){
jc[0]=1;
for(int i=1;i<=maxn;i++) jc[i]=jc[i-1]*(ll)i%ha;
ni[maxn]=ksm(jc[maxn],ha-2);
for(int i=maxn;i;i--) ni[i-1]=ni[i]*(ll)i%ha;
} inline int C(int x,int y){
return jc[x]*(ll)ni[y]%ha*(ll)ni[x-y]%ha;
} inline void solve(){
ll lef,O,y;
for(int i=r;i>=0;i-=2){
if(i>n) continue;
lef=K-i*(ll)m;
O=(n-2*i);
if(!O){
if(lef) continue;
int now=C(n,i)*(ll)C(m+c-1,c)%ha;
now=now*(ll)C(n+((r-i)>>1)-1,(r-i)>>1)%ha;
ans=add(ans,now);
continue;
} if(lef%O) continue;
y=lef/O;
if(y<0||y>c||y>m||((c-y)&1)) continue; int now=C(n,i)*(ll)C(m,y)%ha;
now=now*(ll)C(n+((r-i)>>1)-1,(r-i)>>1)%ha;
now=now*(ll)C(m+((c-y)>>1)-1,(c-y)>>1)%ha;
ans=add(ans,now);
}
} int main(){
init();
scanf("%d%d%d%d%lld",&n,&m,&r,&c,&K);
solve();
printf("%d\n",ans);
return 0;
}

  

T3:

一道比较好的扫描线题。

我们知道当k==1的时候,这就是一个区间 mex 查询 (只不过0不被统计),而这个是一个经典扫描线问题。

我们把那种方法扩展一下,先预处理出[1,i] 的所有答案,然后考虑左端点向右移动1个单位所带来的影响。当然这个也是可以预处理的,只不过完全可以不用后缀可持久化线段树去预处理(这是我一开始的想法),直接用一个set<>记录 i,i+1,,,i+k-1 这些数出现的最近的一个就可以了。虽然处理一个点的复杂度都是 O(k * log)的,但是set是O(k * log k)的,而后缀可持久化线段树查找是O(k *log n)的,而本题k远小于n,所以emmmmmm

/*
xjb扫描线即可
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<vector>
#include<cstdlib>
#include<set>
#define ll long long
using namespace std;
const int maxn=200105;
set<int> s;
struct ask{
int L,R,num;
bool operator <(const ask &u)const{
return L<u.L;
}
}q[maxn];
int n,m,Q,k,ans[maxn],*pos,w,T[maxn];
int a[maxn],las[maxn],le,ri,ops;
int mn[maxn<<2|1],to[maxn][12];
bool v[maxn]; inline void prework(){
ops=1,v[n+1]=1;
for(int i=1,j;i<=m;i++){
v[a[i]]=1;
for(;ops<=n;ops++){
for(j=0;j<k;j++) if(v[ops+j]) break;
if(j==k) break;
}
T[i]=ops;
} for(int i=m;i;las[a[i]]=i,i--){
s.clear();
for(int j=0;j<k;j++) s.insert(las[a[i]+j]);
for(int j=0;j<k&&a[i]-j>0;s.erase(las[a[i]+k-j-1]),j++,s.insert(las[a[i]-j])){
to[i][j]=*s.lower_bound(0);
}
}
} void update(int o,int l,int r){
if(l>=le&&r<=ri){
mn[o]=min(mn[o],w);
return;
}
int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
if(le<=mid) update(lc,l,mid);
if(ri>mid) update(rc,mid+1,r);
} void query(int o,int l,int r){
*pos=min(*pos,mn[o]);
if(l==r) return;
int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
if(le<=mid) query(lc,l,mid);
else query(rc,mid+1,r);
} inline void add(int U){
for(int j=0;j<k&&a[U]-j>0;j++){
le=U+1,ri=to[U][j]-1,w=a[U]-j;
if(le<=ri) update(1,1,n);
}
} inline void solve(){
for(int i=1;i<=Q;i++){
scanf("%d%d",&q[i].L,&q[i].R);
q[i].num=i;
}
sort(q+1,q+Q+1);
int now=1;
for(int i=1;i<=Q;i++){
while(now<q[i].L) add(now),now++;
pos=ans+q[i].num;
*pos=T[q[i].R];
le=q[i].R;
query(1,1,m);
}
} inline void output(){
for(int i=1;i<=Q;i++){
if(ans[i]<=n) printf("%d\n",ans[i]);
else puts("-1");
}
} int main(){
scanf("%d%d%d%d",&n,&m,&Q,&k);
for(int i=1;i<=m;i++) scanf("%d",a+i);
fill(las+1,las+n+1,m+1);
memset(mn,0x7f,sizeof(mn));
prework();
solve();
output();
return 0;
}

  

清北省选 DAY last 集锦的更多相关文章

  1. 清北学堂2017NOIP冬令营入学测试P4745 B’s problem(b)

    清北学堂2017NOIP冬令营入学测试 P4745 B's problem(b) 时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试 描述 题目描 ...

  2. 清北学堂2017NOIP冬令营入学测试 P4744 A’s problem(a)

    清北学堂2017NOIP冬令营入学测试 P4744 A's problem(a) 时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试题,每三天结算 ...

  3. 清北Day 2

    清北第二天,感受到了来自这个世界的不友善,大概把没听过不会的"名词"记录下来就已经一面了,然后被大佬说这都是最基础的东西,就很皮,那就趁别人练习字符串的题的时候,来写波博客了,倒不 ...

  4. 清北Day4

    版权声明:如需转载请标明出处,未得到本人许可请勿转载. 今天就可以看到传说中的 数据结构 嘿嘿嘿嘿 都有什么呢 链表 队列 栈 st表 hash 线段树 树链剖分 一.栈: 放出来这个看烂了的图 值得 ...

  5. 济南清北学堂游记 Day 1.

    快住手!这根本不是暴力! 刷了一整天的题就是了..上午三道题的画风还算挺正常,估计是第一天,给点水题做做算了.. rqy大佬AK了上午的比赛! 当时我t2暴力写挂,还以为需要用啥奇怪的算法,后来发现, ...

  6. 清明培训 清北学堂 DAY1

    今天是李昊老师的讲授~~ 总结了一下今天的内容: 1.高精度算法 (1)   高精度加法 思路:模拟竖式运算 注意:进位 优化:压位 程序代码: #include<iostream>#in ...

  7. 2017.10.1 国庆清北 D1T1 zhx的字符串题

    题目背景 2017国庆清北D1T1 题目描述 你是能看到第一题的 friends 呢. ——hja 何大爷对字符串十分有研究,于是天天出字符串题虐杀 zhx.何大爷今天为 字符串定义了新的权值计算方法 ...

  8. 7月清北学堂培训 Day 3

    今天是丁明朔老师的讲授~ 数据结构 绪论 下面是天天见的: 栈,队列: 堆: 并查集: 树状数组: 线段树: 平衡树: 下面是不常见的: 主席树: 树链剖分: 树套树: 下面是清北学堂课程表里的: S ...

  9. 清北学堂省选刷题冲刺班 Test Day3

    目录 2018.3.27 Test T1 T2 T3 考试代码 T2 T3 2018.3.27 Test 时间:8:00~11:30 期望得分:100+60+25=185 实际得分:100+40+25 ...

随机推荐

  1. 字符串逆序-c语言

    给定一个含有n个元素的字符串,实现逆序. 这是个很基础的问题,实现方式也是很常见的c语言思路.虽然简单,但是仍然记录下来. [期望] 比如char str[] = "abcdefg" ...

  2. Es6里面的解析结构

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  3. HYSBZ 1086 王室联邦 (树的分块)

    题意:国王想把他的国家划分成若干个省.他的国家有n个城市,是一棵树,即n-1条边,编号为1..n.为了防止管理太过分散,每个省至少要有B个城市,为了能有效的管理,每个省最多只有3B个城市.每个省必须有 ...

  4. Halcon学习笔记1

    转:https://www.cnblogs.com/hanzhaoxin/archive/2013/02/15/2912879.html 机器视觉工程应用主要可划分为硬件和软件两大部分. 硬件:工程应 ...

  5. Two-Phase Commit (2PC)

    两阶段提交模式像极了比赛发令:“预备,开始!”

  6. expand - 把 tab 符转换为空格符

    总览 (SYNOPSIS) ../src/expand [OPTION]... [FILE]... 描述 (DESCRIPTION) 把 各文件 FILE 中的 tab 符 转换为 空格符, 然后 写 ...

  7. 总结vue2.0 配置的实例方法

    总结vue2.0 配置的实例方法 http://www.php.cn/js-tutorial-369603.html

  8. python数据类型常用内置函数之字符串

    1.strip, lstrip, rstrip x = ' jiahuifeng ' print(x.strip(' ')) print(x.lstrip(' ')) print(x.rstrip(' ...

  9. mybatis-4 mybatis与spring结合使用及原理

    1.创建项目maven,方便依赖下载.使用的jar如下: <dependencies> <dependency> <groupId>org.springframew ...

  10. 基于jquery的自定义显示消息数量

    根据需求简单的实现一个小功能控件,暂时不支持扩展 $("xxxxxxx").iconCountPlugin(options, start, isOffset) {//三个参数,自定 ...