题意是,给你一个序列,问有多少区间 [l,r] 满足 a[l]%a[l+1]%a[l+2].....%a[r]==a[r]%a[r-1]%a[r-2]...%a[l]?

我们考虑一个区间 [l,r] 假设区间内最小值在pos处取得,那么区间的合法性可以表示为

a[l]%a[l+1]%a[l+2].....%a[pos]==a[r]%a[r-1]%a[r-2]...%a[pos].因为在mod a[pos]之后,值是小于apos的,继续取余比较大的数也没有什么意义。

如果pos==l || pos==r 呢?如果区间内没有等于apos的数,那么区间一定是不合法的。只有区间内有多个等于apos的数才有可能合法,这里需要特判一下。

所以只要统计一个每个最小值左右相等的数的乘积,注意不要计算重复。

可以分治解决这个问题。我们每次找到区间内最小值(多个取最左边的),递归左区间,递归右区间。

对于每一个分治的区间L,R,我们用set去维护所有数向左取模和所有数向右取模。

那么计算的时候,先分别把左区间向右的mod apos, 右区间向左的mod pos,这里注意,取模的时候先二分找到第一个大于apos的值,再向后依次取模,这样保证每次操作都会使一个数变小。(这里的复杂度是nlognlogn的,因为一个最多有效取模log次,那么n个数最多取模nlog次,再算上set的复杂度)。

然后统计答案,合并左右区间。

为了保证分治的复杂度,就是要启发式分治嘛。

统计答案的时候要遍历小的区间,二分大的区间。合并的时候也是把小区间插入到大的区间里去。

这样复杂度也是nloglog的嘛。

#include <bits/stdc++.h>using namespace std;#define N 200025
#define M 610
#define ll long long
#define mod 1000000007
#define go(i,a,b) for(int i=(a);i<=(b);i++)
#define dep(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
#define inf 0x3f3f3f3f
#define ld long double
#define pii pair<int,int>
#define pdd pair<double,double>
#define vi vector<int>
#define madd(a,b) (a+=(b)%mod)%=mod
#define lowb(c,len,x) lower_bound(c+1,c+len+1,x)-c
#define uppb(c,len,x) upper_bound(c+1,c+len+1,x)-c
#define ls i*2+1
#define rs i*2+2
//#define mid (l+r)/2
#define lson l,mid,ls
#define rson mid+1,r,rs
//#define root 1,cnt,0
#define ms(a,b) memset(a,b,sizeof a)
#define muti int T,cas=1;cin>>T;while(T--)
#define lll __int128
#define si short int
#define fi first
#define se second
#define l(x) (x&-x)
#define G(x) for( int ii=h[x];ii;ii=eg[ii].n )int mm[2*N],n,las[N];
int dp[2*N][20],a[N],cnt;
set<pii>st[N];
set<pii>::iterator it,it1,itt;
ll ans=0;
void init()
{mm[0]=-1;go(i,1,n){dp[i][0]=i;mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];}go(j,1,mm[n])for(int i=1; i+(1<<j)-1<=n; i++)dp[i][j]=a[dp[i][j-1]]<=a[dp[i+(1<<(j-1))][j-1]]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1];
}
int quy(int x,int y){if(x>y)return n+1;int k=mm[y-x+1];return a[dp[x][k]]<=a[dp[y-(1<<k)+1][k]]?dp[x][k]:dp[y-(1<<k)+1][k];
}
int join(int x,int y,int z){ //合并两个set,插入a[mid]if(st[x].size()>st[y].size())swap(x,y);//if(!st[x].size())return y;for(it=st[x].begin();it!=st[x].end();it++){it1=st[y].lower_bound(pii(it->fi,0));if(it1==st[y].end()||it1->fi!=it->fi)st[y].insert(*it);else {pii tmp=pii(it1->fi,it1->se+it->se);st[y].erase(it1);st[y].insert(tmp);}}st[x].clear();it=st[y].lower_bound(pii(z,0));if(it!=st[y].end()&&it->fi==z){pii tmp=pii(it->fi,it->se+1);st[y].erase(it);st[y].insert(tmp);}else st[y].insert(pii(z,1));return y;
}
void cal(int x,int y){ //统计答案if(st[x].size()>st[y].size())swap(x,y);if(!st[x].size())return ;for(it=st[x].begin();it!=st[x].end();it++){it1=st[y].lower_bound(pii(it->fi,0));if(it1!=st[y].end()&&it1->fi==it->fi)ans+=1ll*(it->se)*(it1->se);}
}
//void pri(int x){
//    cout<<":::::::::::::"<<endl;
//    for(it=st[x].begin();it!=st[x].end();it++){
//        cout<<it->fi<<'-'<<it->se<<' ';
//    }
//    cout<<endl<<endl;
//}
void upd(int x,int y){ //对set所有的值 mod a[mid]for(it=st[x].lower_bound(pii(y,0));it!=st[x].end();){pii tmp=pii(it->fi%y,it->se);it1=it;it++;st[x].erase(it1);itt=st[x].lower_bound(pii(tmp.fi,0));if(itt!=st[x].end()&&itt->fi==tmp.fi){pii tmp1=pii(itt->fi,itt->se+tmp.se);st[x].erase(itt);st[x].insert(tmp1);}else st[x].insert(tmp);}
}pii solve(int l,int r,int fl=0){ if(fl)ans++;if(l>=r){if(l>r)return pii(++cnt,++cnt);//cout<<fl<<endl;st[++cnt].insert(pii(a[l],1));st[++cnt].insert(pii(a[l],1));return pii(cnt-1,cnt);}int mid=quy(l,r);//递归左右区间pii pl=solve(l,mid-1),pr=solve(mid+1,r,a[quy(mid+1,r)]==a[mid]?1:0),res;//分别取模a[mid]upd(pr.fi,a[mid]);upd(pl.se,a[mid]);//特判区间内有多个相同的最小值it=st[pr.fi].lower_bound(pii(0,0));if(it!=st[pr.fi].end()&&it->fi==0)ans+=fl*(it->se);//统计答案cal(pl.se,pr.fi);//合并左右区间,a[mid]res=pii(join(pl.fi,pr.fi,a[mid]),join(pl.se,pr.se,a[quy(mid+1,r)]==a[mid]?0:a[mid]));return res;
}int main()
{cin>>n;go(i,1,n)scanf("%d",&a[i]);a[n+1]=inf;init();solve(1,n);cout<<ans+n<<endl;
}
/*
10
10 9 8 7 1 2 3 4 5 6
*/

GYM 102439 Equal Mod Segments相关推荐

  1. Diffie–Hellman key exchange

    原文地址:https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange Diffie–Hellman key exchange F ...

  2. MOD - Power Modulo Inverted(SPOJ3105) + Clever Y(POJ3243) + Hard Equation (Gym 101853G ) + EXBSGS

    思路: 前两题题面相同,代码也相同,就只贴一题的题面了.这三题的意思都是求A^X==B(mod P),P可以不是素数,EXBSGS板子题. SPOJ3105题目链接:https://www.spoj. ...

  3. Codeforces gym 2013-2014 Samara SAU ACM ICPC Quarterfinal Qualification Contest

    题目地址:http://codeforces.com/gym/100247 2014.10.27版 26号训练的题,今天发现A题有更高效的解法,用到了前缀最大值和后缀最大值 A. The Power ...

  4. Codeforces gym 100685 C. Cinderella 水题

    C. Cinderella Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100685/problem/ ...

  5. codeforces Gym 100187B B. A Lot of Joy

    B. A Lot of Joy Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/proble ...

  6. TVM/Relay 的 PartitionGraph()(mod) 函数讨论整理

    TVM/Relay 的 PartitionGraph()(mod) 函数讨论整理 TVM/Relay 的图形分区功能.以下简单示例,错误信息. PartitionGraph() 函数指定图形是用带有 ...

  7. codeforces 610D D. Vika and Segments(离散化+线段树+扫描线算法)

    题目链接: D. Vika and Segments time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  8. Codeforces Gym 100513G G. FacePalm Accounting 暴力

    G. FacePalm Accounting Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100513 ...

  9. Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树扫描线

    D. Vika and Segments 题目连接: http://www.codeforces.com/contest/610/problem/D Description Vika has an i ...

最新文章

  1. loadrunner—参数化
  2. 测试build出来的dist文件夹是否编译成功
  3. Windows Server 2012 网络负载均衡
  4. 最简单的 SAP Cloud Application programming CDS 练习
  5. 计算机基础知识 pdf答案,计算机基础知识练习 答案版.pdf
  6. java项目短信群发接口_JAVA实现第三方短信发送过程详解
  7. Python操作mySql数据库封装类
  8. springboot_通过Actuator了解应用程序运行时的内部状况
  9. HDU 1114 Piggy-Bank 简单DP
  10. OpenHarmony 1.1.0 LTS 版本发布,十六大性能全面提升
  11. ❤️Java面试高频《注解与反射》(建议收藏)❤️
  12. C++ 编译运行报错 error: stray ‘\200’ in program 解决方案
  13. Intel 处理器 ME 管理引擎是无法移除的安全隐患
  14. 员工考勤管理系统html,网页考勤系统人员排班操作说明
  15. android zip winrar,WinRAR Zip Unzip Archive
  16. Mantis集成富文本插件
  17. EM78P468 义隆单片机 单键触控
  18. 1-4 CAD 圆弧(arc)
  19. Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)
  20. Arduino造轮子—FlashSRAM优化代码

热门文章

  1. winds10桌面彻底关闭系统更新
  2. C++设计模式 - 观察者模式(Observer)
  3. JS入门到入土之数字运算符扩展
  4. 云计算时代,建站选择虚拟主机还是云服务器
  5. Mysql 查询所有的上级,下级
  6. 一款值得使用的会议室预约软件【叮当会议小程序】
  7. RGB、YUY2、YUYV、YVYU、UYVY、AYUV
  8. 我还能走很远---lua和tolua++
  9. DCI-P3广色域显示器的支持现状
  10. 还在为PS抠图头疼?试试PPT这个功能,一学就会!