• [日常摸鱼]bzoj1271秦腾与教学评估-二分


    https://darkbzoj.tk/problem/1271

    题意:一个无限长的数列,下标从1开始,开始全为0,现在给(n)个操作((s_i,e_i,d_i))表示让(s_i,s_i+d_i,s_i+2d_i,dots,s_i+kd_i(s_i+kd_ileq e_i &s_i+(k+1)d_i>e_i))这些位置+1,同时保证最后至多有一个位置的值是奇数,回答是否存在这样的位置,如果存在则输出位置。

    题解:至多只有一个位置非常关键,虽然原数列可能是:偶…偶奇偶…,但是考虑前缀和的话就会变成:偶…偶奇奇…,好的有二分性质了…

    现在就只要考虑给一个位置(x)怎么快速求对应的前缀和就行,发现也很简单…如果不考虑(e_i)这个东西,那第(i)个操作的贡献就直接是(egin{aligned}1+lfloorfrac{x-s_i}{d_i} floorend{aligned}),有(e_i)的话(x)变成(min(x,e_i))就行啦…于是就能(O(nlog m))地做了,(m)是值域。

    
    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define per(i,a,b) for(int i=(a);i>=(b);i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef vector<int> vi;
    const int N=2e5+5;
    const int M=(~0u>>1);
    int n,T;
    int S[N],D[N],E[N];
    ll check(int x)
    {
    	ll res=0;
    	rep(i,1,n)if(x>=S[i])
    	{
    		if(x>=E[i])res+=1ll*(1+(E[i]-S[i])/D[i]);
    		else res+=1ll*(1+(x-S[i])/D[i]);
    	}
    	return res;
    }
    int main()
    {
    	scanf("%d",&T);
    	rep(tc,1,T)
    	{
    		scanf("%d",&n);
    		rep(i,1,n)scanf("%d%d%d",&S[i],&E[i],&D[i]);
    		ll l=0,r=M;
    		while(r>l)
    		{
    			ll mid=(l+r)>>1;
    			ll t=check(mid);
    			if(t&1ll)r=mid;
    			else l=mid+1;
    		}
    		ll t=check(l);
    		if(t&1ll)printf("%d %lld
    ",l,check(l)-check(l-1));
    		else printf("Poor QIN Teng:(
    ");
    	}
    	return 0;
    }
  • 相关阅读:
    案例------存储过程
    案例------冒泡排序
    案例------递归调用
    天气预报接口api(中国天气网)
    【转】ubuntu64,ndk-r9 编译 ffmpeg 2.1.1的config文件
    android权限大全
    JNI 回调小记
    java设置环境变量小工具
    bootstrap之双日历时间段选择控件—daterangepicker(汉化版)
    一个 bootstrap 弹出框插件
  • 原文地址:https://www.cnblogs.com/yoshinow2001/p/14467007.html
Copyright © 2020-2023  润新知