洛谷 P4964 绫小路的特别考试 解题报告
P4964 绫小路的特别考试
题目背景
这世界上「胜利」便是一切。无关乎过程。
要付出多少牺牲都无所谓。只要最后我「胜出」那就行了。

题目描述
一场新的特别考试来临了,这次的考试内容是(wan e de)文化课,但有所不同的是,考试中允许学生使用对讲机。然而,对讲机的接收范围有限(每个对讲机都能发送无限远,但是只能接收到接收范围内的信号),所以,需要周密地安排才能将对讲机的功效发挥到最大。这时,绫小路找到了你,希望你能帮他计算某种方案下的结果。
考试时,共有 \(n\) 名学生坐成一排(从左至右依次编号为 \(1\) ~ \(n\)),绫小路自己坐在第 \(c\) 号位置。每名学生都有一个能力值 \(w_i\)。绫小路已经给每名学生安排了一个接收范围为 \(d_i\) 的对讲机。
每名学生可以直接做出难度不超过自身能力值的所有题目,一旦一名学生凭能力做出某道题,他就会把这道题的做法进行广播。一名坐在位置 \(i\),有接收范围为 \(d_i\) 的对讲机的学生,可以接收到 \([i-d_i,\ i+d_i]\) 范围内所有学生的广播,若这个范围内有人公布了做法,则他将会做这道题,并也会把这道题的做法进行广播。
绫小路会问你一些问题:当一道题目难度为 \(x\) 时,有多少学生会做这道题?由于绫小路想隐藏实力,他可能会修改自己的能力值。这两种操作分别用以下两种方式表示:
- \(1\ x\),表示询问当一道题目难度为 \(x\) 时,有多少学生会做这道题。
- \(2\ x\),将绫小路的能力值修改为 \(x\),即将 \(w_c\) 修改为 \(x\)。
形式化描述(与上文同义):
给你两个长为 \(n\) 的数列 \(w_{1..n}\) 和 \(d_{1..n}\),以及一个 \(w_c\) 可修改的位置 \(c\)。现在有两种操作:
- \(1\ x\) 表示一次询问:设 \(f_i=\begin{cases}1\quad(w_i\ge x)\\1\quad(\exists\ i-d_i\le j\le i+d_i,f_j=1)\\ 0\quad(otherwise)\end{cases}\),这里的 \(f_i\) 定义中引用了 \(f_j\),$\ \ \ \ $所以 \(f_{1..n}\) 是会不断更新的,直到无法继续更新时,计算这次询问的答案为 \(\sum\limits_{i=1}^nf_i\)。
- \(2\ x\) 表示一次修改:把 \(w_c\) 修改为 \(x\)。
输入输出格式
输入格式
由于数据量太大,为了避免读入耗时过长,使用伪随机数生成器的方式输入,并强制在线。
建议你忽略输入格式,直接使用下面提供的数据生成器模板,了解具体的生成过程对你来说是不必要的。
第一行,三个正整数 \(n,\ m,\ c\),分别代表学生的总人数,操作总数和绫小路所在的位置。
第二行,五个整数 \(\mathrm{seed},\ \mathrm{mind},\ \mathrm{maxd},\ \mathrm{mfq},\ k\)。
此处的 \(\mathrm{mind},\ \mathrm{maxd}\) 仅用于生成初始的 \(d_{1..n}\),下文中调整 \(d_p\) 所用的 \(t\) 可能不在 \([\mathrm{mind},\ \mathrm{maxd}]\) 范围内。
接下来的 \(k\) 行,每行两个整数 \(p,\ t\),表示调整第 \(p\) 号同学的对讲机接收范围(即 \(d_p\))为 \(t\)。
若一名同学的对讲机接收范围被调整多次,以最后一次为准。
** 数据生成器模板:**
#include <cstdio>
unsigned long long seed;
int n, m, c, mfq, mind, maxd, k, w[2000001], d[2000001];
inline int randInt() { seed = 99999989 * seed + 1000000007; return seed >> 33; } 
void generate()
{
	// 在读入种子后生成初始的 w 数组和 d 数组.
    for (int i = 1; i <= n; i++) { w[i] = randInt() % n; }
    for (int i = 1; i <= n; i++) { d[i] = randInt() % (maxd - mind + 1) + mind; }
}
void getOperation(int lastans, int &opt, int &x)
{
    // 生成一次操作的参数 opt 和 x, lastans 表示上一次询问的答案, 初始值为 0.
    if ((0ll + randInt() + lastans) % mfq) { opt = 1; } else { opt = 2; }
    x = (0ll + randInt() + lastans) % n;
}
int main()
{
    scanf("%d %d %d", &n, &m, &c);
    scanf("%llu %d %d %d %d", &seed, &mind, &maxd, &mfq, &k);
    generate();
    for (int i = 1; i <= k; i++)
    {
        int p, t;
        scanf("%d %d", &p, &t);
        d[p] = t;
    }
    // 从这里开始,你可以使用生成的 w 数组和 d 数组.
    int lastans = 0, finalans = 0;
    for (int i = 1; i <= m; i++)
    {
        int opt, x;
        getOperation(lastans, opt, x);
        if (opt == 1)
        {
            // 在这里执行询问操作,并用答案的表达式替代下面的 ___.
            finalans = (finalans * 233ll + ___) % 998244353;
            lastans = ___;
        }
        else
        {
            // 在这里执行修改操作.
        }
    }
    printf("%d\n", finalans);
    return 0;
}
输出格式
令 \(ans_i\) 表示第 \(i\) 次询问(操作 \(1\) )的答案,\(T_i=\begin{cases}(T_{i-1}\times 233+ans_i)\mod 998244353\quad(i\ge 1)\\0\quad(i=0)\end{cases}\)
设 \(q\) 表示询问(操作 \(1\) )的个数,你只需要输出一个整数 \(T_q\)。
说明
你需要用到的变量:
\(1\le c\le n\le 2\times 10^6\),\(1\le m\le 2\times 10^6\),\(0\le w_i,\ d_i,\ x<n\)。
其它用于生成数据的变量:
\(1\le \mathrm{seed},\ \mathrm{mfq}\le 10^9\),\(0\le \mathrm{mind}\le \mathrm{maxd}<n\),\(0\le k\le 2\times 10^5\),\(1\le p\le n\),\(0\le t<n\)。
思路很简单但是为什么想不出来的一个题目??
考虑暴力,每个点向可以接收到\(\tt{Ta}\)的点连有向边,这样从每个点出发可以遍历到的点都是\(\tt{Ta}\)可以把答案传出去的点。这样连边是\(O(n^2)\)的
考虑优化连边,发现找离它最近左右的可以连到\(\tt{Ta}\)的点就可以了。
实现的时候拿个栈就可以维护了。
发现修改每次只改一个位置的值,可以特殊处理\(\tt{Ta}\)
预处理出每个询问在路哥传不传答案时的贡献。
可以把元素排序以后从大到小进行\(\tt{dfs}\),并每次记录被染色的点。
排序可以桶排,计数排序保证复杂度,也可以直接\(\tt{sort}\),跑的也挺快的。
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
unsigned long long seed;
const int N=2e6+10;
int n,m,c,mfq,mind,maxd,k,d[N],ans[2][N];
struct node
{
    int w,id;
    bool friend operator <(node n1,node n2){return n1.w>n2.w;}
}w[N];
inline int randInt(){seed=99999989*seed+1000000007;return seed>>33;}
void generate()
{
    for(int i=1;i<=n;i++)w[i].w=randInt()%n,w[i].id=i;
    for(int i=1;i<=n;i++)d[i]=randInt()%(maxd-mind+1)+mind;
}
void getOperation(int lastans,int &opt,int &x)
{
    if((0ll+randInt()+lastans)%mfq)opt=1;
    else opt=2;
    x=(0ll+randInt()+lastans)%n;
}
int sum,used[N],wc,ch[N][2],s[N],tot;
int max(int x,int y){return x>y?x:y;}
void dfs(int now)
{
    if(used[now]) return;
    used[now]=1;
    ++sum;
    dfs(ch[now][0]),dfs(ch[now][1]);
}
void init()
{
    for(int i=1;i<=n;i++)
    {
        while(tot&&s[tot]+d[s[tot]]<i) --tot;
        if(tot) ch[i][0]=s[tot];
        s[++tot]=i;
    }
    tot=0;
    for(int i=n;i;i--)
    {
        while(tot&&s[tot]-d[s[tot]]>i) --tot;
        if(tot) ch[i][1]=s[tot];
        s[++tot]=i;
    }
    std::sort(w+1,w+1+n);used[0]=1;
    for(int i=1;i<=n;i++)
    {
        if(w[i].id==c) {wc=w[i].w;continue;}
        dfs(w[i].id);
        ans[0][w[i].w]=sum;
    }
    memset(used,0,sizeof(used));
    used[0]=1,sum=0,dfs(c);
    for(int i=1;i<=n;i++)
    {
        dfs(w[i].id);
        ans[1][w[i].w]=sum;
    }
    for(int i=N-10;~i;i--) ans[0][i]=max(ans[0][i],ans[0][i+1]),ans[1][i]=max(ans[1][i],ans[1][i+1]);
}
int main()
{
    scanf("%d%d%d",&n,&m,&c);
    scanf("%llu%d%d%d%d",&seed,&mind,&maxd,&mfq,&k);
    generate();
    for (int p,t,i=1;i<=k;i++) scanf("%d%d",&p,&t),d[p]=t;
    init();
    int lastans=0,finalans=0;
    for(int ___,opt,x,i=1;i<=m;i++)
    {
        getOperation(lastans,opt,x);
        if(opt==1)
        {
            if(wc>=x) ___=ans[1][x];
            else ___=ans[0][x];
            finalans=(finalans*233ll+___)%998244353;
            lastans=___;
        }
        else
            wc=x;
    }
    printf("%d\n",finalans);
    return 0;
}
2018.11.7
洛谷 P4964 绫小路的特别考试 解题报告的更多相关文章
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur 解题报告
		P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 约翰有\(n\)块草场,编号1到\(n\),这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可 ... 
- 【洛谷】CYJian的水题大赛 解题报告
		点此进入比赛 \(T1\):八百标兵奔北坡 这应该是一道较水的送分题吧. 理论上来说,正解应该是DP.但是,.前缀和优化暴力就能过. 放上我比赛时打的暴力代码吧(\(hl666\)大佬说这种做法的均摊 ... 
- 洛谷 P1337 [JSOI2004]平衡点 / 吊打XXX 解题报告
		P1337 [JSOI2004]平衡点 / 吊打XXX 题目描述 有 \(n\) 个重物,每个重物系在一条足够长的绳子上.每条绳子自上而下穿过桌面上的洞,然后系在一起.\(X\)处就是公共的绳结.假设 ... 
- 洛谷 P3143 [USACO16OPEN]钻石收藏家Diamond Collector 解题报告
		P3143 [USACO16OPEN]钻石收藏家Diamond Collector 题目描述 Bessie the cow, always a fan of shiny objects, has ta ... 
- 洛谷 P4151 [WC2011]最大XOR和路径 解题报告
		P4151 [WC2011]最大XOR和路径 题意 求无向带权图的最大异或路径 范围 思路还是很厉害的,上午想了好一会儿都不知道怎么做 先随便求出一颗生成树,然后每条返祖边都可以出现一个环,从的路径上 ... 
- 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告
		P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ... 
- 洛谷 P2420 让我们异或吧 解题报告
		P2420 让我们异或吧 题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中-xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B ... 
- 洛谷 P3102 [USACO14FEB]秘密代码Secret Code 解题报告
		P3102 [USACO14FEB]秘密代码Secret Code 题目描述 Farmer John has secret message that he wants to hide from his ... 
- 洛谷 P2341 [HAOI2006]受欢迎的牛 解题报告
		P2341 [HAOI2006]受欢迎的牛 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的"喜欢&q ... 
随机推荐
- 获取附加在方法上的Attribute
			如下: class Program { static void Main(string[] args) { var methodInfo = typeof(Program).GetMethod(&qu ... 
- Python 更换国内pip源
			pip国内的一些镜像: 阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/sim ... 
- 在页面使用echarts的地图(解决地图不完整)
			测试环境:IDEA+Tomcat7 谷歌浏览器 创建好web工程,编写jsp页面,在自己编写的JSP页面上导包 现在echarts停止了在其网站上下载地图脚本,直接通过src引用网站上的china.j ... 
- NOIP2019普及级别模拟 3.30校模拟
			好吧我还是第一次写这种总结类的玩意… 考场心情…hmm…我没睡醒.是的是这样的,反正题都有两三个看错了或者没看懂… 最关键的是!!我!居!然!把!Freopen!写!在!了!程!序!最!后! 然后就和 ... 
- Python入门(5)
			导览: 函数 集合 迭代器与生成器 模块 一.函数 只要学过其他编程语言应该对函数不太陌生,函数在面向过程的编程语言中占据了极重要的地位,可以说没有函数,就没有面向过程编程,而在面向对象语言中,对象的 ... 
- springMVC对jsp页面的数据进行校验
			一. 使用注解校验 a) 引入校验依赖包 <dependency> <groupId>javax.validation</groupId> <artifact ... 
- windows store无法登陆的问题解决方案
			Windows应用商店或商店Apps无法打开或闪退的可选方法 (仅用于10565之前的Windows 10版本) 右键点击任务栏,选择"属性",切换到"导航"选 ... 
- GitHub把自己整个文件夹上传
			我已经有了自己github,但是我怎么对我的项目进行上传呢,普通的上传只有上传单一的文件 这不我去下载了Git(链接至机房ftp文件夹下文件ftp://10.64.130.1/%C8%ED%BC%FE ... 
- LVS+Keepalive+Nginx实现负载均衡
			本文参考:http://blog.csdn.net/yinwenjie/article/details/47211551 简单粗暴写一下,做备忘,刚刚搭好没做优化呢,后期补充 一.机器准备 LVS-M ... 
- 【转】c++面试基础
			1,关于动态申请内存 答:内存分配方式三种: (1)从静态存储区域分配:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在. 全局变量,static变量. (2)在栈上创建:在执行函 ... 
