zoukankan      html  css  js  c++  java
  • [Ynoi2013]大学

    题目传送门

    题意

    • 非负整数序列,支持 区间和查询 和 区间所有某数倍数除以其。

    Sol

    真就卡常 最后改成指针才行

    考虑一个数的因数个数不超过 (2sqrt{a_i}),不妨对每个因数开链表,记录其倍数位置。

    考虑每个数最多能被操作 (log{a_i}) 次,我们每次暴力修改链表就行了。

    区间和可以写个 BIT,毕竟常数小。(

    总复杂度 (O(nsqrt{a_i}+nlog nlog {a_i}))

    // wish to get better qwq
    
    #include<bits/stdc++.h>
    #define re register int
    #define pb push_back
    
    using namespace std;
    typedef long long ll;
    
    template <typename T> void rd(T &x){
    	int fl=1;x=0;char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') fl=-fl;
    	for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
    	x*=fl;
    }
    void wr(ll x){
    	if(x<0) x=-x,putchar('-');
    	if(x<10) putchar(x+'0');
    	if(x>9) wr(x/10),putchar(x%10+'0');
    }
    
    // ---------- IO ---------- //
    
    const int N=5e5+5;
    int n,m,a[N];
    vector<int> f[N],fa[N];
    
    ll sum[N],ans;
    
    inline int lowbit(int x){return x&(-x);}
    
    inline void add(int x,ll k){
    	while(x<=n) sum[x]+=k,x+=lowbit(x);
    }
    
    inline ll query(int x){
    	ll s=0;
    	while(x) s+=sum[x],x-=lowbit(x);
    	return s;
    }
    
    // ---------- BIT ---------- //
    
    inline int found(int pos,int x){
    	if(x>=fa[pos].size()) return x;
    	return fa[pos][x]==x?fa[pos][x]:fa[pos][x]=found(pos,fa[pos][x]);
    }
    
    // ---------- DSU ---------- //
    
    int main(){
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	rd(n);rd(m);
    	for(re i=1;i<=n;++i){
    		rd(a[i]);add(i,a[i]);
    		for(re j=1;j*j<=a[i];++j)
    			if(a[i]%j==0){
    				f[j].pb(i);fa[j].pb(fa[j].size());
    				if(j*j!=a[i]) f[a[i]/j].pb(i),fa[a[i]/j].pb(fa[a[i]/j].size());
    			}
    	}
    	int op,l,r,x;
    	for(re i=1;i<=m;++i){
    		rd(op);rd(l);rd(r);l^=ans;r^=ans;
    		if(op==1){
    			rd(x);x^=ans;
    			if(x==1) continue;
    			int st=lower_bound(f[x].begin(),f[x].end(),l)-f[x].begin();
    			for(re j=found(x,st);j<f[x].size()&&f[x][j]<=r;j=found(x,j+1)){
    				if(a[f[x][j]]%x==0) add(f[x][j],a[f[x][j]]/x-a[f[x][j]]),a[f[x][j]]/=x;
    				if(a[f[x][j]]%x!=0) fa[x][j]=found(x,j+1);
    			}
    		}
    		else wr(ans=query(r)-query(l-1)),puts("");
    	}
    	return 0;
    }
    
    // ---------- Main ---------- //
    

    然后你就发现被卡常了

    预计得分 (62)

    我们考虑卡常。(

    把数组全部改成指针即可。(

    注意细节,不要 (<=) 写成 (<)。(

    会 RE 飞。(

    // wish to get better qwq
    
    #include<bits/stdc++.h>
    #define re register int
    #define pb push_back
    #define lb lower_bound
    #define ub upper_bound
    
    using namespace std;
    typedef long long ll;
    
    template <typename T> void rd(T &x){
    	int fl=1;x=0;char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') fl=-fl;
    	for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
    	x*=fl;
    }
    void wr(ll x){
    	if(x<0) x=-x,putchar('-');
    	if(x<10) putchar(x+'0');
    	if(x>9) wr(x/10),putchar(x%10+'0');
    }
    
    // ---------- IO ---------- //
    
    const int N=5e5+5;
    int n,m,a[N],cnt[N],maxn,*p[N],node[N*505],*tp=node;
    
    ll sum[N],ans;
    
    inline int ma(int x,int y){return x<y?y:x;}
    
    inline void add(int x,ll k){
    	while(x<=n) sum[x]+=k,x+=x&(-x);
    }
    
    inline ll query(int x){
    	ll s=0;
    	while(x) s+=sum[x],x^=x&(-x);
    	return s;
    }
    
    // ---------- BIT ---------- //
    
    struct DSU{
    	int *fa;
    	inline void init(int n){for(re i=0;i<n;++i) fa[i]=i;}
    	inline int found(int x){return fa[x]==x?x:fa[x]=found(fa[x]);}
    }nxt[N];
    
    // ---------- DSU ---------- //
    
    inline void modify(int l,int r,int x){
    	l=lb(p[x],p[x]+cnt[x],l)-p[x];
    	r=ub(p[x],p[x]+cnt[x],r)-p[x]-1;
    	if(l>r) return ;
    	for(re nw=nxt[x].found(l);nw<=r;nw=nxt[x].found(nw+1)){
    		int t=p[x][nw];
    		if(a[t]%x==0) add(t,a[t]/x-a[t]),a[t]/=x;
    		if(nw>=r) break;
    		if(a[t]%x) nxt[x].fa[nw]=nxt[x].found(nw+1);
    	}
    }
    
    int main(){
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	rd(n);rd(m);
    	for(re i=1;i<=n;++i){
    		rd(a[i]);add(i,a[i]);
    		cnt[a[i]]++;maxn=ma(maxn,a[i]);
    	}
    	for(re i=1;i<=maxn;++i)
    		for(re j=i+i;j<=maxn;j+=i) cnt[i]+=cnt[j];
    	for(re i=1;i<=maxn+1;++i)
    		if(cnt[i]){
    			p[i]=tp;tp+=cnt[i];
    			nxt[i].fa=tp;nxt[i].init(cnt[i]);
    			tp+=cnt[i];cnt[i]=0;
    		}
    	for(re i=1;i<=n;++i){
    		for(re j=1;j*j<=a[i];++j)
    			if(a[i]%j==0){
    				p[j][cnt[j]++]=i;
    				if(j*j!=a[i]) p[a[i]/j][cnt[a[i]/j]++]=i;
    			}
    	}
    	int op,l,r,x;
    	for(re i=1;i<=m;++i){
    		rd(op);rd(l);rd(r);l^=ans;r^=ans;
    		if(op==1){
    			rd(x);x^=ans;
    			if(x==1) continue;
    			modify(l,r,x);
    		}
    		else wr(ans=query(r)-query(l-1)),puts("");
    	}
    	return 0;
    }
    
    // ---------- Main ---------- //
    
  • 相关阅读:
    Python学习札记(十五) 高级特性1 切片
    LeetCode Longest Substring Without Repeating Characters
    Python学习札记(十四) Function4 递归函数 & Hanoi Tower
    single number和变体
    tusen 刷题
    实验室网站
    leetcode 76. Minimum Window Substring
    leetcode 4. Median of Two Sorted Arrays
    leetcode 200. Number of Islands 、694 Number of Distinct Islands 、695. Max Area of Island 、130. Surrounded Regions 、434. Number of Islands II(lintcode) 并查集 、178. Graph Valid Tree(lintcode)
    刷题注意事项
  • 原文地址:https://www.cnblogs.com/danieljiang/p/daxue.html
Copyright © 2011-2022 走看看