HDU5286 wyh2000 and sequence

题意:

给出长为\(N\)的序列\(A_1,A_2,A_3,\cdots,A_n\),\(q\)次询问,每次询问给出区间\([L,R]\),假设区间内出现过的数为\(C_1,C_2,\cdots,C_k\),出现的次数分别为\(B_1,B_2,\cdots,B_k\),输出\(\sum_{i=1}^{k}C_i^{B_i} % 1000000007\),要求在线

题解:

如果不要求在线,直接用莫队很快就能解决,现在要求在线,还是考虑把序列分块,预处理出所有连续的块的答案,和到第\(i\)块为止,各个数出现的次数的前缀和

对于每次查询,如果在一个块内,就直接暴力查询

否则对于在两端非整块的元素,记录元素大小和出现次数,将这些元素带来的贡献计算一下即可

有点卡常

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MOD = 1e9+7;
const int MAXN = 5e4+7;
const int SQT = 240;
int n,q,m,sqt,A[MAXN],pre[SQT][MAXN],pos[MAXN],belong[MAXN],l[SQT],r[SQT],la;
int ans[SQT][SQT],num[MAXN];
vector<int> vec,cnt,pw[MAXN];
void divide(){
sqt = pow(n,0.5);
m = n / sqt + (n%sqt?1:0);
for(int i = 1; i <= n; i++) belong[i] = (i-1) / sqt + 1;
for(int i = 1; i <= m; i++) l[i] = (i-1) * sqt + 1, r[i] = i * sqt;
r[m] = n;
}
void gao(){
int L, R;
scanf("%d %d",&L,&R);
L = (L^la)%n+1; R = (R^la)%n+1;
if(L>R) L ^= R ^= L ^= R;
int lp = belong[L], rp = belong[R];
if(lp==rp){
int ret = 0;
for(int i = L; i <= R; i++) num[pos[i]] = 0;
for(int i = L; i <= R; i++){
ret = ret - pw[pos[i]][num[pos[i]]];
ret = ret + pw[pos[i]][++num[pos[i]]];
if(ret<0) ret += MOD;
if(ret>=MOD) ret -= MOD;
}
printf("%d\n",la=ret);
}
else{
vector<int> arr;
for(int i = L; i <= r[lp]; i++){
num[pos[i]] = 0;
arr.push_back(pos[i]);
}
for(int i = l[rp]; i <= R; i++){
num[pos[i]] = 0;
arr.push_back(pos[i]);
}
sort(arr.begin(),arr.end()); arr.erase(unique(arr.begin(),arr.end()),arr.end());
for(int i = L; i <= r[lp]; i++) num[pos[i]]++;
for(int i = l[rp]; i <= R; i++) num[pos[i]]++;
lp++, rp--;
int ret = ans[lp][rp];
for(int i = 0; i < (int)arr.size(); i++){
ret = ret - pw[arr[i]][pre[rp][arr[i]]-pre[lp-1][arr[i]]];
ret = ret + pw[arr[i]][pre[rp][arr[i]]-pre[lp-1][arr[i]]+num[arr[i]]];
if(ret<0) ret += MOD;
if(ret>=MOD) ret -= MOD;
}
printf("%d\n",la=ret);
}
}
void solve(){
scanf("%d %d",&n,&q);
vec.clear();
for(int i = 1; i <= n; i++){
scanf("%d",&A[i]);
vec.push_back(A[i]);
}
sort(vec.begin(),vec.end()); vec.erase(unique(vec.begin(),vec.end()),vec.end());
for(int i = 1; i <= n; i++) pos[i] = lower_bound(vec.begin(),vec.end(),A[i]) - vec.begin();
divide();
for(int i = 1; i <= m; i++) for(int j = 0; j < (int)vec.size(); j++) pre[i][j] = 0;
for(int i = 1; i <= n; i++) pre[belong[i]][pos[i]]++;
for(int i = 1; i <= m; i++) for(int j = 0; j < (int)vec.size(); j++) pre[i][j] += pre[i-1][j];
cnt.resize(vec.size());
for(int i = 0; i < (int)vec.size(); i++) cnt[i] = 0;
for(int i = 1; i <= n; i++) cnt[pos[i]]++;
for(int i = 0; i < (int)vec.size(); i++){
pw[i].resize(cnt[i]+1);
pw[i][0] = 1; for(int j = 1; j <= cnt[i]; j++) pw[i][j] = 1ll * pw[i][j-1] * vec[i] % MOD;
pw[i][0] = 0;
}
for(int i = 1; i <= m; i++){
memset(num,0,sizeof(num));
int p = l[i] - 1, ret = 0;
for(int j = i; j <= m; j++){
while(p<r[j]){
p++;
ret -= pw[pos[p]][num[pos[p]]];
ret += pw[pos[p]][++num[pos[p]]];
if(ret<0) ret += MOD;
if(ret>=MOD) ret -= MOD;
}
ans[i][j] = ret;
}
}
la = 0;
while(q--) gao();
for(int i = 0; i < (int)vec.size(); i++) pw[i].clear();
}
int main(){
int T;
for(scanf("%d",&T); T; T--) solve();
return 0;
}

HDU5286 wyh2000 and sequence【分块 均摊复杂度】的更多相关文章

  1. Mr. Kitayuta's Colorful Graph CodeForces - 506D(均摊复杂度)

    Mr. Kitayuta has just bought an undirected graph with n vertices and m edges. The vertices of the gr ...

  2. cf250D. The Child and Sequence(线段树 均摊复杂度)

    题意 题目链接 单点修改,区间mod,区间和 Sol 如果x > mod ,那么 x % mod < x / 2 证明: 即得易见平凡, 仿照上例显然, 留作习题答案略, 读者自证不难. ...

  3. 3L-最好、最坏、平均、均摊时间复杂度

    关注公众号 MageByte,设置星标点「在看」是我们创造好文的动力.后台回复 "加群" 进入技术交流群获更多技术成长. 本文来自 MageByte-青叶编写 上次我们说过 时间复 ...

  4. 洛谷 P6783 - [Ynoi2008] rrusq(KDT+势能均摊+根号平衡)

    洛谷题面传送门 首先显然原问题严格强于区间数颜色,因此考虑将询问离线下来然后用某些根号级别复杂度的数据结构.按照数颜色题目的套路,我们肯定要对于每种颜色维护一个前驱 \(pre\),那么答案可写作 \ ...

  5. Chapter4 复杂度分析(下):浅析最好,最坏,平均,均摊时间复杂度

    四个复杂度分析: 1:最好情况时间复杂度(best case time complexity) 2:最坏情况时间复杂度(worst case time complexity) 3:平均情况时间复杂度( ...

  6. 【loj6029】「雅礼集训 2017 Day1」市场 线段树+均摊分析

    题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有四种:区间加.区间下取整除.区间求最小值.区间求和. $n\le 100000$ ,每次加的数在 $[-10^4,10^4]$ 之 ...

  7. 【uoj#228】基础数据结构练习题 线段树+均摊分析

    题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有三种:区间加.区间开根.区间求和. $n,m,a_i\le 100000$ . 题解 线段树+均摊分析 对于原来的两个数 $a$ ...

  8. HDU - 6098:Inversion(暴力均摊)

    Give an array A, the index starts from 1. Now we want to know B i =max i∤j A j  Bi=maxi∤jAj , i≥2 i≥ ...

  9. 《数据结构与算法之美》 <02>复杂度分析(下):浅析最好、最坏、平均、均摊时间复杂度?

    上一节,我们讲了复杂度的大 O 表示法和几个分析技巧,还举了一些常见复杂度分析的例子,比如 O(1).O(logn).O(n).O(nlogn) 复杂度分析.掌握了这些内容,对于复杂度分析这个知识点, ...

随机推荐

  1. 【Java】面向对象 - 封装

    继承 封装 多态 重新搞一波 复习巩固 简单记录 慕课网 imooc Java 零基础入门-Java面向对象-Java封装 封装 封装是什么? 将类的某些信息隐藏在类内部,不允许外部程序直接访问 通过 ...

  2. Jenkins自动部署spring boot

    Jenkins自动部署spring boot 背景介绍 本公司属于微小型企业,初期业务量不高,所有程序都写在一个maven项目里面,不过是多模块开发. 分了login模块,service模块,cms模 ...

  3. 为什么不建议用var

    看了这个例子估计你就会明白了 var a = 'global'; function test() { if (!a) { var a = 'part'; } console.log(a); } tes ...

  4. centos7虚拟机开启端口后 外部不能访问的问题

    转载 https://blog.csdn.net/u012045045/article/details/104219823 虚拟机新开了5005端口,系统内部是显示开了的(wget 192.168.4 ...

  5. 【高并发】ReadWriteLock怎么和缓存扯上关系了?!

    写在前面 在实际工作中,有一种非常普遍的并发场景:那就是读多写少的场景.在这种场景下,为了优化程序的性能,我们经常使用缓存来提高应用的访问性能.因为缓存非常适合使用在读多写少的场景中.而在并发场景中, ...

  6. 1.5V转3V电源芯片,1.5V转3V稳压芯片

    1.5V干电池的供电电压一般是0.9V-1.6V左右,因为供电电压不稳,所以需要1.5V转3V的稳压电源芯片,当0.9V-1.6V输入电压时,输出电压能稳定3V输出,给模块供电,MCU供电,LED灯供 ...

  7. PAT练习num2-挖掘机技术哪家强

    为了用事实说明挖掘机技术到底哪家强,PAT 组织了一场挖掘机技能大赛.现请你根据比赛结果统计出技术最强的那个学校. 输入格式: 输入在第 1 行给出不超过 1 的正整数 N,即参赛人数.随后 N 行, ...

  8. web项目启动链接mysql巨慢

    说明:项目部署到测试服务器上,mysql部署在另一台服务器上,项目第一次启动之后登陆后台很慢,大概30s左右,经查发现第一次访问数据库的时候会通过DNS解析客户端机器域名,mysql还有DNS反向解析 ...

  9. Python hashlib的简单使用

    hashlib模块针对不同的安全哈希和消息摘要算法实现了一个通用的接口,其中包括SHA1, SHA224, SHA256, SHA384, SHA512算法以及RSA的MD5算法. 使用方法 第一步 ...

  10. Cisco发现协议

    CDP Cisco Discovery Protocol: 思科发现协议 是一个提供关于直接相连的交换机.路由器和其它Cisco设备的综合信息的专有工具 CDP 能够发现直接相邻的设备而不管这些设备所 ...