HDOJ 5726 线段树 + map

来源:互联网 发布:证件照蓝底渐变软件 编辑:程序博客网 时间:2024/06/04 22:06

这个map我也是醉了。

这个 主要是 那个   不同gcd值得区间数预处理难弄。

a[1...i]=a[1...i-1]+a[i...i];  当前区间:不同的gcd值相对应的区间数=之前区间:不同的gcd值相对应的区间数+gcd(num[i],之前区间的某个gcd);

#include"iostream"#include"vector"#include"set"#include"queue"#include"algorithm"#include"map"#include"cstdio"#include"cstring"#include"string"#define sf scanf#define pf printf#define INF 100000000000000#define eps 1e-6#define FP freopen("a.txt","r",stdin);using namespace std;typedef long long ll;const int maxn=100010;int a[maxn*4];int b[maxn];map<int,ll>ans,m1,m2;int gcd(int a,int b){return b==0?a:gcd(b,a%b);}void up(int rt){a[rt]=gcd(a[rt<<1],a[rt<<1|1]);}void build(int L,int R,int rt){if(L==R){a[rt]=b[L];return ;}int Mid((L+R)/2);build(L,Mid,rt<<1);build(Mid+1,R,rt<<1|1);up(rt);}int query(int l,int r,int L,int R,int rt){if(l==L&&R==r) return a[rt];int Mid=(L+R)/2;int res;if(r<=Mid)return query(l,r,L,Mid,rt<<1); //必定在左子树else if(l>Mid)return query(l,r,Mid+1,R,rt<<1|1);//必定在右子树else return gcd(query(l,Mid,L,Mid,rt<<1),query(Mid+1,r,Mid+1,R,rt<<1|1));}int main(){//FPint Case=1;int T;sf("%d",&T);while(T--){m1.clear();m2.clear();ans.clear();int n;sf("%d",&n);for(int i=1;i<=n;i++)sf("%d",b+i);build(1,n,1);//map<int,ll>::iterator it;//for(int i=1;i<=n;i++)     //      {  //          ans[b[i]]++;  //          m2[b[i]]++;  //          for(it=m1.begin();it!=m1.end();it++)  //          {  //              ll k=gcd(b[i],it->first);  //              ans[k]+=it->second;  //              m2[k]+=it->second;  //          }  //          m1.clear();  //          for(it=m2.begin();it!=m2.end();it++)  //              m1[it->first]=it->second;  //          m2.clear();                                                           //      }map<int,ll>::iterator p;for(int i=1;i<=n;i++)   // ans记录的是从1-n 中不同gcd的区间数{                       //m2存储的是当前状态下不同gcd的区间数 然后复制给m1,那么下一次的时候m1存放的就是i-1的状态ans[b[i]]++;m2[b[i]]++;for(p=m1.begin();p!=m1.end();p++){int k=gcd(p->first,b[i]);ans[k]+=p->second;m2[k]+=p->second;}/*cout<<"i="<<i<<endl;cout<<"ans:"<<endl;for(p=ans.begin();p!=ans.end();p++)cout<<"gcd="<<p->first<<"的区间数:"<<p->second<<endl;cout<<"m1:"<<endl;for(p=m1.begin();p!=m1.end();p++)cout<<"gcd="<<p->first<<"的区间数:"<<p->second<<endl;cout<<"m2:"<<endl;for(p=m2.begin();p!=m2.end();p++)cout<<"gcd="<<p->first<<"的区间数:"<<p->second<<endl<<endl;*/m1.clear();m1=m2;m2.clear();}printf("Case #%d:\n",Case++);int Q;sf("%d",&Q);for(int i=0;i<Q;i++){int L,R;sf("%d%d",&L,&R);int num=query(L,R,1,n,1);pf("%d %I64d\n",num,ans[num]);}}return 0;}


0 0
原创粉丝点击