牛客小白93

被俘虏

a-d省略

e  线段树

#include<bits/stdc++.h>
using namespace std; 
const int N=2e5+6;
namespace modnum_space {
	typedef long long ll;
	const ll pmod = 998244353;
	struct modnum;
	modnum inv(modnum a);
	ll exgcd(ll a, ll b, ll &x, ll &y);
	modnum qpow(modnum a, modnum b, modnum p);
	
	struct modnum {
		ll val;
		modnum(){ val = 0; }
		modnum(ll a) { val = (a%pmod+pmod)%pmod; }
		modnum(int a) { val = (a%pmod+pmod)%pmod; }
		friend modnum operator + (const modnum &a, const modnum &b){ return (a.val+b.val)%pmod; }
		friend modnum operator - (const modnum &a, const modnum &b){ return (a.val-b.val+pmod)%pmod; }
		friend modnum operator * (const modnum &a, const modnum &b){ return (a.val*b.val)%pmod; }
		friend modnum operator / (const modnum &a, const modnum &b){ return (a.val*inv(b.val)).val%pmod; }
		friend modnum& operator += (modnum &a, const modnum &b){ return a = a+b; }
		friend modnum& operator -= (modnum &a, const modnum &b){ return a = a-b; }
		friend modnum& operator *= (modnum &a, const modnum &b){ return a = a*b; }
		friend modnum& operator /= (modnum &a, const modnum &b){ return a = a/b; }
	};
	
	modnum inv(modnum a)
	{
		ll x, y;
		exgcd(a.val, pmod, x, y);
		x = (x%pmod+pmod)%pmod;
		return x;
	}
	modnum qpow(modnum a, ll b)
	{
		modnum ans = 1;
		for(; b; b >>= 1, a *= a)
			if(b&1) ans *= a;
		return ans;
	}
	ll exgcd(ll a, ll b, ll &x, ll &y)
	{
		if(b == 0){ return x = 1, y = 0, a; }
		ll d = exgcd(b, a%b, x, y);
		ll z = x; x = y; y = z-(a/b)*y;
		return d;
	}
	
	
#ifdef _GLIBCXX_IOSTREAM
	std::istream& operator >> (std::istream& cin, modnum &a)
	{ cin >> a.val; a.val %= pmod; return cin; }
	std::ostream& operator << (std::ostream& cout, modnum a)
	{ cout << a.val; return cout; }
#endif
}
using namespace modnum_space;
#define z modnum
#define ls(i) (i<<1)
#define rs(i) (i<<1|1)
int a[N];
int mod=1e9;
long long gcd(long long x, long long y) {
	return y ? gcd(y, x % y) : x;
}
int n;
string s;
struct node
{	int l,r;
	z w;
	ll w0,w1;//数量
	ll x0,x1;//
}tr[N << 2];
struct sb{
	node  hb(node a,node b){
		int mid=a.r;
		
		node c;
		c.w=a.w+b.w;
		c.w1=a.w1+b.w1;
		c.w0=a.w0+b.w0;
		c.x0=a.x0+b.x0;
		c.x1=a.x1+b.x1;
		
		c.w+=(mid*a.w1-a.x1)*b.w0
		+(mid*a.w0-a.x0)*b.w1
		+(b.x1-mid*b.w1)*a.w0
		+(b.x0-mid*b.w0)*a.w1;
		c.r=b.r;
		c.l=a.l;
		return c;
	}
	void push_up(int i){
		int mid=tr[ls(i)].r;
		
		tr[i].w=tr[ls(i)].w+tr[rs(i)].w;
		tr[i].w1=tr[ls(i)].w1+tr[rs(i)].w1;
		tr[i].w0=tr[ls(i)].w0+tr[rs(i)].w0;
		tr[i].x0=tr[ls(i)].x0+tr[rs(i)].x0;
		tr[i].x1=tr[ls(i)].x1+tr[rs(i)].x1;
		
		tr[i].w+=(mid*tr[ls(i)].w1-tr[ls(i)].x1)*tr[rs(i)].w0
		+(mid*tr[ls(i)].w0-tr[ls(i)].x0)*tr[rs(i)].w1
		+(tr[rs(i)].x1-mid*tr[rs(i)].w1)*tr[ls(i)].w0
		+(tr[rs(i)].x0-mid*tr[rs(i)].w0)*tr[ls(i)].w1;
		
	}
	void build (int l,int r,int i){
		tr[i].l=l;
		tr[i].r=r;
		if(l==r){
			tr[i].w=0;
			tr[i].w1+= a[l]==1? 1:0;
			tr[i].w0+= a[l]==0? 1:0;
			tr[i].x0+=a[l]==0? l:0;
			tr[i].x1+=a[l]==1? l:0;
			return;
		}
		int mid=l+r>>1;
		build(l,mid,ls(i));
		build(mid+1,r,rs(i));
		push_up(i);
	}
	node query1(int ql,int qr,int l,int r,int i){
		if(ql<=l&&r<=qr){
			return tr[i];
		}
		
		node ans;
		int mid=l+r>>1;
		//cout<<l<<' '<<' '<<r<<'\n';
		if(ql<=mid&&qr>mid){
			node a=query1(ql,qr,l,mid,ls(i));
			node b=query1(ql, qr, mid + 1, r, rs(i));
			ans=hb(a,b);
		}
		else if(ql<=mid){
			node a=query1(ql,qr,l,mid,ls(i));
			ans=a;
		}
		else{
			node b=query1(ql, qr, mid + 1, r, rs(i));
			ans=b;
		}
		return ans;
	}
}s1;
int q;
void solve() {
	cin>>n>>q;
	cin>>s;
	for(int i=0;i<n;i++){
		a[i+1]=s[i]-'0';
	}
	s1.build(1,n,1);
	while(q--){
		int l,r;
		cin>>l>>r;
		node ans=s1.query1(l,r,1,n,1);
		
		cout<<ans.w<<'\n';
	}
}


signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int t = 1;
	// cin >> t;
	while(t--){
		solve();
	}
	return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值