zoukankan      html  css  js  c++  java
  • HDU7055 Yiwen with Sqc 推式子

    HDU7055 Yiwen with Sqc 推式子

    题意

    (sqc(s,i,j,c))表示字符串(s)中字符(c)在区间([l,r])出现次数

    [sum_{c=97}^{122}sum_{i=1}^nsum_{j=i}^n sqc(s,i,j,c)^2 ]

    [1 leq T leq 100\ |s| leq 10^5 ]

    分析

    题解的做法太巧妙 没有想到,万能的笨办法:枚举端点

    考虑对每个字符分别求和

    把字符串中等于当前位置的字符看成1,否则看成0,这样相当于求1的前缀和平方

    枚举左端点,我们就可以试图去维护这样的东西,因为1的贡献就是(sum i^2) 可以根据当前1的个数直接求,我们只需要维护0的贡献

    把连续的0分段,得到0的贡献就是(sum cnt[i]j^2)

    考虑左端点右移对0的贡献的影响就是(cnt[i]j^2 -> cnt[i](j-1)^2 = cnt[i]j^2 - cnt[i]2j + cnt[i])

    发现第一项不变,第二项可以继续维护,第三项可以预处理后缀和,第二项维护方法仍然类似,考虑左端点又移可能的影响(cnt[i]2j -> cnt[i]2(j-1) -> cnt[i]2j - cnt[i])

    这样就能够(O(1))维护了

    代码

    调试了很久,这类题一定要想清楚过程再写,否则一定是浪费机时

    #include<bits/stdc++.h>
    #define pii pair<ll,ll>
    #define fi first
    #define se second
    #define int long long
    using namespace std;
    typedef long long ll;
    
    inline ll rd(){
    	ll x;
    	scanf("%lld",&x);
    	return x;
    }
    
    
    const int maxn = 1e5 + 5;
    const int MOD = 998244353;
    
    inline int mul(int a,int b){
    	return (ll)a * b % MOD;
    }
    
    inline void add(int &a,int b){
    	a += b;
    	if(a >= MOD) a -= MOD;
    }
    
    inline int ksm(int a,int b = MOD - 2,int m = MOD){
    	int ans = 1;
    	int base = a;
    	while(b){
    		if(b & 1) ans = mul(ans,base);
    		base = mul(base,base);
    		b >>= 1;
    	}
    	return ans;
    }
    
    char s[maxn];
    int Get[maxn];
    
    
    int suf[maxn];
    int Suf[maxn];
    
    int main(){
    	//freopen("input.txt","r",stdin);
    	int T = rd();
    	for(int i = 1;i < maxn;i++){
    		Get[i] = Get[i - 1] + (ll)i * i % MOD;
    		if(Get[i] >= MOD) Get[i] -= MOD;
    	}
    	while(T--){
    		scanf("%s",s);
    		int n = strlen(s);
    		int ans = 0;
    		int mulsuf;
    		for(char ch = 'a';ch <= 'z';ch++){
    			for(int i = 0;i <= n + 1;i++)
    				suf[i] = Suf[i] = 0;
    			mulsuf = 0;
    			int cnt = 0;
    			int cnt_1 = 0;
    			for(int i = 0;i < n;i++)
    				if(s[i] != ch) suf[cnt]++;
    				else {
    					cnt_1++;
    					if(suf[cnt]) add(mulsuf,(ll)2 * suf[cnt++] * (cnt_1 - 1) % MOD); 
    				}
    			if(!suf[cnt]) cnt--;
    			if(s[n - 1] != ch) add(mulsuf,(ll)2 * suf[cnt] * (cnt_1) % MOD);
    			if(!cnt_1) continue;
    			Suf[cnt + 1] = 0;
    			for(int i = cnt;i >= 0;i--){
    				Suf[i] = Suf[i + 1] + suf[i];
    				if(Suf[i] >= MOD) Suf[i] -= MOD;
    			}
    			/*
    			if(ch == 'a') {
    				cout << cnt << '
    ';
    				for(int i = 0;i <= cnt;i++)
    					cout << suf[i] << ' ';
    				puts("");
    				for(int i = 0;i <= cnt;i++)
    					cout << Suf[i] << ' ';
    				puts("");
    			}*/
    			
    			/*
    			for(int i = st,j = 1;i <= cnt;i++,j++){
    				add(mulsuf,2 * j * suf[i]);
    			}*/
    			int lst = 0;
    			int sb = 0;
    			for(int i = 0;i < n;i++){
    				if(s[i] == ch) sb++;
    				add(lst,mul(sb,sb));
    			}
    			add(ans,lst);
    			int fro = !(s[0] == ch);
    			int Lst = lst - Get[cnt_1];
    			Lst = (Lst + MOD) % MOD;
    			
    			for(int i = 1;i < n;i++){
    				//if(ch == 'a') cout << i << ' ' << mulsuf << ' ' << lst << ' ' << Lst << '
    ';
    				if(s[i - 1] != ch) {
    					add(ans,lst);
    				}
    				else if(s[i - 1] == ch && s[i] == ch) {
    					cnt_1--;
    					lst = Get[cnt_1];
    					Lst -= mulsuf;
    					add(Lst,MOD);
    					add(Lst,Suf[fro]);
    					mulsuf -= (2 * Suf[fro]) % MOD;
    					add(mulsuf,MOD);
    					//add(Lst,Suf[fro]);
    					//fro++;
    					add(lst,Lst);
    					add(ans,lst);
    				}
    				else if(s[i - 1] == ch && s[i] != ch) {
    					cnt_1--;
    					lst = Get[cnt_1];
    					Lst -= mulsuf;
    					add(Lst,Suf[fro]);
    					add(Lst,MOD);
    					mulsuf -= (2 * Suf[fro]) % MOD;
    					add(mulsuf,MOD);
    					//add(Lst,Suf[fro]);
    					fro++;
    					add(lst,Lst);
    					add(ans,lst);
    				}
    			}
    			//cout << ans << '
    ';
    		}
    		printf("%d
    ",ans);
    	}
    }
    
    
    
    
  • 相关阅读:
    TestNg 2.套件测试
    JBPM工作流
    Spring 事务详解
    数据库事务隔离级别及传播行为
    Spring AspectJ基于注解的AOP实现
    Spring 通知(Advice)和顾问(Advisor)
    Spring 代理模式及AOP基本术语
    Spring之BeanFactory及Bean生命周期
    Spring 02多种注入方式和注解实现DI
    Spring 01基础
  • 原文地址:https://www.cnblogs.com/hznumqf/p/15178078.html
Copyright © 2011-2022 走看看