zhx p111

T1咕

区间除法(若可整除),区间求和

1≤N,M≤10^5,0≤a1,a2,a3...an≤10^6,1≤v≤10^6,1≤l≤r≤N

注意:

1.数组开大了会RE!!! 最好不要超过107  (ytez的oj上过了 6*107

2.一个数的约数个数上限是 √n  然而远远不到 所以链表数组不用开到 103*105

  1 #include<cstring>
  2 #include<cstdio>
  3 #include<iostream>
  4 #include<cctype>
  5 #include<algorithm>
  6 typedef long long ll;
  7 using namespace std;
  8 inline int gi(){
  9     int d=0;char c=getchar();while(!isdigit(c))c=getchar();
 10     while(isdigit(c)){d=(d<<3)+(d<<1)+c-'0';c=getchar();}
 11     return d;
 12 }
 13 /*
 14 #ifdef WIN32
 15 #define LL "%I64d"
 16 #else 
 17 #define LL "%lld"
 18 #endif
 19 */
 20 #define gem int mi=(l+r)>>1
 21 #define lson o<<1,l,mi
 22 #define rson o<<1|1,mi+1,r
 23 const int N=100005;
 24 const int M=N*70;
 25 const int maxa=1000001;
 26 ll t[N<<4];
 27 int x[N];
 28 inline void UP(int o){t[o]=t[o<<1]+t[o<<1|1];}
 29 void bud(int o,int l,int r){
 30     if(l==r){t[o]=x[l];return;}
 31     gem;bud(lson);bud(rson);UP(o);
 32 }
 33 void gai(int o,int l,int r,int P,int C){
 34     if(l==r){t[o]=C;return;}
 35     gem;if(P<=mi)gai(lson,P,C);else gai(rson,P,C);
 36     UP(o); 
 37 }
 38 ll qur(int o,int l,int r,int TL,int TR){
 39     if(l>=TL&&r<=TR)return t[o];
 40     gem;ll ret=0;
 41     if(mi>=TL)ret+=qur(lson,TL,TR);
 42     if(mi<TR)ret+=qur(rson,TL,TR);
 43     return ret;
 44 }
 45 struct NO{
 46     int v,p;
 47 }y[M];
 48 bool wu[M];
 49 int lst[maxa],fst[maxa],nxt[M],pre[M];
 50 #define rep(a,b,c) for(a=b;a<=c;++a)
 51 #define drp(a,b,c) for(a=b;a>=c;--a)
 52 bool cmp1(NO a,NO b){
 53     if(a.v==b.v)return a.p<b.p;return a.v<b.v;
 54 }
 55 int cnt;
 56 int n,m,L,R,opt,V;
 57 int main(){
 58     freopen("pk.in","r",stdin);freopen("pk.out","w",stdout);
 59     register int i,j;
 60     n=gi();m=gi();
 61     rep(i,1,n){
 62         x[i]=gi();
 63         for(j=2;j*j<=x[i];++j){
 64             if(x[i]%j==0){
 65                 y[++cnt].p=i;y[cnt].v=j;
 66                 if(j*j!=x[i]){
 67                     y[++cnt].p=i;y[cnt].v=x[i]/j; 
 68                 }
 69             }
 70         }
 71         if(x[i]>1){
 72             y[++cnt].p=i;y[cnt].v=x[i];
 73         }            
 74     }
 75     bud(1,1,n);
 76     sort(y+1,y+cnt+1,cmp1); 
 77     rep(i,1,cnt)lst[y[i].v]=i;
 78     drp(i,cnt,1)fst[y[i].v]=i;
 79     rep(i,1,cnt){
 80         if(y[i].v==y[i+1].v)nxt[i]=i+1;
 81         if(y[i].v==y[i-1].v)pre[i]=i-1;
 82     }
 83 //    rep(i,1,cnt)printf("%d %d %d %d %d %d %d\n",i,y[i].v,y[i].p,lst[y[i].v],fst[y[i].v],nxt[i],pre[i]);
 84     while(m--){
 85         opt=gi();L=gi();R=gi();
 86         if(opt==2){
 87             cout<<qur(1,1,n,L,R)<<endl;
 88             //printf("%lld\n",qur(1,1,n,L,R));
 89         }else{
 90             V=gi();
 91             if(V<=1)continue;
 92             if(!fst[V])continue;
 93             for(i=fst[V];y[i].p<L&&y[i].v==V;i=nxt[i]);
 94             for(;y[i].p>=L&&y[i].p<=R&&y[i].v==V;i=nxt[i]){
 95                 if(!wu[i]){
 96                     if(x[y[i].p]%V==0){
 97                         x[y[i].p]/=V;
 98                         gai(1,1,n,y[i].p,x[y[i].p]);
 99                     }
100                     if(x[y[i].p]%V!=0){
101                         wu[i]=1;
102                         if(!pre[i]&&!nxt[i])fst[V]=lst[V]=0;
103                         else if(!pre[i]){
104                             fst[V]=nxt[i];pre[nxt[i]]=0;
105                         }else if(!nxt[i]){
106                             lst[V]=pre[i];nxt[pre[i]]=0;
107                         }else{
108                             nxt[pre[i]]=nxt[i];
109                             pre[nxt[i]]=pre[i];
110                         }
111                     }                    
112                 }
113             }
114         }
115     }
116     return 0;
117 }

 

 

 

3.链表连nxt和pre的时候注意判断合法性

4.二分查找 能不用还是别用了吧,除了必须用才能过复杂度的情况

样例输入
5 3
1 2 3 4 5
2 1 5
1 1 3 2
2 1 5
样例输出
15
14

 

 

T3咕咕咕

对两个点集做加法S1+S2=S3,求S3凸包面积的两倍

【样例输入】
4 5
0 0
2 1
0 1
2 0
0 0
1 0
0 2
1 2
0 1
【样例输出】
18

求凸包步骤:

1.必须按坐标排序(否则无法用叉积实现极角排序)!!!!!!!!!!!!!

2.按极角排序(用叉积实现)

3.不断用当前点弹出栈中不合法的点

4.用栈底的点弹出栈中不合法的点

求凸包加法注意事项

1.可能会转一圈回到第0个点,所以需要取模操作(可用减法代替)

 

  1 #include<cstring>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cctype>
  5 #include<iostream>
  6 using std::sort;
  7 using std::swap;
  8 using std::cout;
  9 #define rep(x,y,z) for(x=y;x<=z;++x)
 10 typedef long long ll;
 11 inline int gi(){int d=0,f=1;char c=getchar();
 12 while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
 13 while(isdigit(c)){d=(d<<3)+(d<<1)+c-'0';c=getchar();}
 14 return d*f;
 15 }
 16 const int N=100005;
 17 struct NO{
 18     int x,y;
 19     NO(){}
 20     NO(int _x,int _y){x=_x;y=_y;}
 21     ll crs(const NO &t){
 22         ll ret;ret=(ll)x*t.y-(ll)y*t.x;
 23         return ret;
 24     }
 25     NO operator -(const NO &t){
 26         NO ret;ret.x=x-t.x;ret.y=y-t.y;
 27         return ret;
 28     }
 29     ll dis(const NO &t){
 30         ll ret;ret=(ll)(t.x-x)*(t.x-x)+(ll)(t.y-y)*(t.y-y);
 31         return ret;
 32     } 
 33     NO operator+(const NO &t){
 34         NO ret;ret.x=x+t.x;ret.y=y+t.y;
 35         return ret;
 36     }
 37 }a[N],b[N],za[N],zb[N],zc[N<<2],O;
 38 bool cm1(NO A,NO B){
 39     NO pta=A-O,ptb=B-O;
 40     if(pta.crs(ptb)>0||(pta.crs(ptb)==0&&pta.dis(O)<ptb.dis(O)))return 1;
 41     return 0;
 42 }
 43 bool cm2(NO A,NO B){
 44     if(A.y==B.y)return A.x<B.x;return A.y<B.y;
 45 }
 46 int n,m,k,atp,btp,ctp;
 47 ll area=0;
 48 int main(){
 49     freopen("ppk.in","r",stdin);freopen("ppk.out","w",stdout);
 50     n=gi();m=gi();register int i,j;
 51     a[0].x=gi();a[0].y=gi();
 52     rep(i,1,n-1){
 53         a[i].x=gi();a[i].y=gi();
 54     }
 55     sort(a,a+n,cm2);
 56     O=a[0];
 57     sort(a+1,a+n,cm1);
 58     za[0]=O;za[1]=a[1];atp=2;
 59     rep(i,2,n-1){
 60         while(atp>1&&(za[atp-1]-za[atp-2]).crs(a[i]-za[atp-1])<=0)--atp;
 61         za[atp]=a[i];++atp;
 62     }
 63     while(atp>1&&(za[atp-1]-za[atp-2]).crs(a[0]-za[atp-1])<=0)--atp;
 64     b[0].x=gi();b[0].y=gi();
 65     rep(i,1,m-1){
 66         b[i].x=gi();b[i].y=gi();
 67     }
 68     sort(b,b+m,cm2);
 69     O=b[0];
 70     sort(b+1,b+m,cm1);
 71     zb[0]=O;zb[1]=b[1];btp=2;
 72     rep(i,2,m-1){
 73         while(btp>1&&(zb[btp-1]-zb[btp-2]).crs(b[i]-zb[btp-1])<=0)--btp;
 74         zb[btp]=b[i];++btp;
 75     }
 76     while(btp>1&&(zb[btp-1]-zb[btp-2]).crs(b[0]-zb[btp-1])<=0)--btp;
 77     zc[0]=za[0]+zb[0];i=0;j=0;ctp=1;
 78     while(1){//printf("%d  %d\n",i,j);
 79         NO aa=za[(i+1)%atp]+zb[j];NO bb=zb[(j+1)%btp]+za[i];
 80         if((aa-zc[ctp-1]).crs(bb-zc[ctp-1])>0||
 81         ((aa-zc[ctp-1]).crs(bb-zc[ctp-1])==0&&
 82         aa.dis(zc[ctp-1])<bb.dis(zc[ctp-1]))){
 83             ++i;if(i>=atp)i-=atp;O=aa;
 84         }else {
 85             ++j;if(j>=btp)j-=btp;O=bb;
 86         }
 87         while(ctp>1&&(zc[ctp-1]-zc[ctp-2]).crs(O-zc[ctp-2])<=0)--ctp;
 88         zc[ctp]=O;++ctp;
 89         if(i==0&&j==0)break;
 90     }
 91     while(ctp>1&&(zc[ctp-1]-zc[ctp-2]).crs(zc[0]-zc[ctp-2])<=0)--ctp;    
 92     
 93     
 94     rep(i,0,ctp-2){
 95         area+=(zc[i].crs(zc[i+1]));
 96     }
 97     area+=(zc[ctp-1].crs(zc[0]));
 98     cout<<area;
 99     return 0;
100 }

 

posted @ 2018-04-02 14:23  better?  阅读(149)  评论(0编辑  收藏  举报