首页 > 其他分享 >数列询问

数列询问

时间:2023-07-30 20:01:36浏览次数:31  
标签:数列 int 询问 fa 区间 preS

题目描述

有一个长度为n的数列,数列中每个数都是[0,p-1]之间的整数。

小明不知道数列中每个数的值,所以向小红做了m次询问。

每次小明会向小红询问一个区间[l,r]  中所有数的和对p取模的结果。

问完所有问题后,小明发现小红的回答中似乎存在矛盾。

现在小明想找到最大的 X,满足小红的前X次回答中不存在矛盾( X有可能等于m )。

输入格式

第一行三个整数n,m,p。分别 表示数列长度 ,询问个数  和模数 。

之后m行, 每行三个整数l,r,k , 表示小红回答区间[l,r]  中所有数的和对 p 取模结果为 k 。

输出格式

输出最大的 ,满足小红的前  次回答中不存在矛盾。

样例

样例输入

10 5 2
1 2 0
3 4 1
5 6 0
1 6 0
7 10 1

样例输出

3

数据范围与提示

  

分析:

一个数列确定后,各区间的和是确定的。不同区间的和之间是有关系的。

譬如:若数列A的 【1,5】区间和是25,【1,2】区间和是11,那么【3,5】的区间和一定是14,若不是14就矛盾了。

 如果两个区间有相同的左边界,那两个区间的差区间的区间和是固定的,可以用这个固定值来判定对这个差区间询问是否矛盾。

A数列区间[L,R] 的和 可以用前缀和的差来表示:preS[R]-preS[L-1]

于是使用前缀和把各区间的之间的关系转化为点与点之间的关系。

 一个询问 L,R,K 就表示 preS[R]-preS[L-1]=k 那么preS[R]=preS[L-1]+k 

如何判定当前询问的区间是之前某两个区间的差区间呢?

我们用并查集来维护若干连续区间。fa[R]=L-1。

询问1:区间【1,5】和为 25;

含义是:preS[5]-preS[0]=25;
因fa[5]<>fa[0] 所以令 fa[5]=0

询问2:区间【1,2】和为 11;

含义是:preS[2]-preS[0]=11;
因fa[2]<>fa[0] 所以令 fa[2]=0

询问3:区间【3,5】和为 14;

含义是:preS[5]-preS[2]=14;
因fa[5]==fa[2] ==0,区间的两个端点拥有共同的左边界.(说明它是某个两个区间的差区间)

 

参考代码

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define re register 
 4 #define LL long long
 5 inline int read(){
 6     int f=1,lzx=0;    char c=getchar();
 7     while((c>'9')||(c<'0')){if(c=='-') f=-f; c=getchar();}
 8     while(c<='9' && c>='0'){lzx=lzx*10+c-'0';c=getchar();}
 9     return lzx*f;    
10 }//快读 
11 
12 const int MAXN = 1e6+10;
13 int n,m,p,fa[MAXN];
14 int preS[MAXN];//preS[i]  表示a1、a2 ……ai 之和。前缀和。l、r间的区间 和可以用preS[r]-preS[l-1]表示 
15 
16 inline int find(int x){
17     if(fa[x]==x) return x;
18     int fax=fa[x];
19     fa[x]=find(fa[x]);
20     preS[x]=(preS[x]+preS[fax]) %p;
21     return fa[x] ;
22 }
23 
24 inline void merge(int a,int b,int c){
25     int l=find(a),r=find(b);
26     fa[r]=l;
27     preS[r]=(preS[a]+c-preS[b]+p)%p;
28     return ;
29 }
30 int main() {     
31     n=read();m=read();p=read();
32     for(re int i=1;i<=n;i++) fa[i]=i;
33     
34     int ans=m; 
35     for(int i=1;i<=m;i++){
36         int a=read()-1,b=read(),c=read();
37         int l=find(a),r=find(b);
38         if(l!=r) merge(a,b,c);
39         else{
40             if((preS[a]+c)%p!=(preS[b]%p)) {
41                 ans=i-1;
42                 break;
43             }
44         }
45     }    
46     printf("%d\n",ans);
47     return 0;
48 }

 

 

标签:数列,int,询问,fa,区间,preS
From: https://www.cnblogs.com/flatte/p/17591450.html

相关文章

  • 斐波纳契数列 IIPython
    斐波纳契数列II:Python1.引言斐波纳契数列(Fibonaccisequence)是一个经典的数列,起源于13世纪的意大利数学家列昂纳多·斐波那契(LeonardoFibonacci)。这个数列的定义如下:F(0)=0F(1)=1F(n)=F(n-1)+F(n-2)(n>1)即,数列的第0个元素为0,第1个元素为1,之后的每个元素都是......
  • 2023/7/22 (递推数列的极限)
    ......
  • python斐波那契数列兔子编程
    Python斐波那契数列兔子编程引言斐波那契数列是一个非常经典的数学问题,也是编程中常见的例题之一。它的起源可以追溯到古希腊数学家斐波那契(Fibonacci),他在13世纪的《算盘书》中首次提出了这个数列。斐波那契数列具有很多有趣的特性,而且在计算机科学中有广泛的应用。本文将通过Pyt......
  • P4000 斐波那契数列
    P4000斐波那契数列题意求\[fib_n\pmod{p}\]\[n\leqslant10^{30000000},p<2^{31}\]SolutionideabyItst对于如此庞大的\(n\),一个显而易见的思路为寻找斐波那契数列在模数\(p\)下的循环节。我们可以做以下简便计算,如果说二元组\((fib_n,fib_{n+1})\)与\((f......
  • windows打开此类文件前总是询问怎么解决
    打开此类文件前总是询问怎么解决这个一直提示的问题呢?下面来教大家一个方法杜绝再提示:开始-->运行-->gpedit.msc(组策略)-->用户配置-->管理模板-->windows组件-->附件管理器-->右击"中等危险文件类型的包含列表"-->属性-->选"已启用"-->在"指定中等危险......
  • HJ100 等差数列
    1.题目读题HJ100 等差数列  考查点 2.解法思路 等差数列是指从第二项起,每一项与它的前一项的差等于同一个常数的一种数列。这个常数叫做等差数列的公差,公差常用字母d表示。等差数列的通项公式是:an=a1+(n-1)d,其中a1是首项,an是第n项,n是正整数。等差数列的前n项......
  • P1438 无聊的数列
    原题链接戳这里考试的时候打的这道题硬是想了半天想不出来回来一看觉得自己真的智慧等差数列的意思是什么?在一个数列的第二项及以后所有的项与前一项的差值相同将这一点反应到差分数组中去如原数列:000000等差数列:13579现数列:135790现等差数列1......
  • P5550 Chino的数列
    很想模拟,但是数据太大啦(悲。然后我想着用\(map\)映射来做,想着模拟几轮发现周期,然后映射求解。但是不知道为什么写崩了。勉强贴贴,反正不是正解(#include<bits/stdc++.h>#definelllonglong#definereregisterusingnamespacestd;constintN=80+10,INF=0x3f3f3f3f;lln,......
  • 高等数学——数列的极限
    数列的极限定义数列:\(x_{1},x_{2},\dots,x_{n},\dots\)是一个从小到大的序列,称为数列,记为\(\{x_{n}\}\)其中\(x_{1}\)叫做项,\(x_{n}\)称为通项(一般项)。数列极限:设\(\{x_{n}\}\)是一个数列,\(\forall\varepsilon>0,\existsN\),使当\(n>N\)时,$|x_{n}-a|<\varepsilon$......
  • 快速等比数列求和
    快速等比数列求和1.等比数列求和公式要求给定的取余的数是质数,能求出逆元2.递归分解如果有偶数个,那么分解成两半,左边就为\(a_0+a_0q+a_0q^2...+a_0q^{n/2}\),另一半为\(a_0q^{n/2+1}+a_0q^{n/2+2}+a_0q^{n/2+3}...+a_0q^{n}\),令等比数列求和为一个函数\(f(n)\),就有\(f(n)=f......