1 条题解

  • 0
    @ 2025-10-8 16:55:53

    二分

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 2e5+5;
    struct node{ll st,ed,d;}a[N];
    int n;
    ll S(ll x)//计算前缀和
    {
    	ll res= 0;
    	for(int i=1;i<=n;i++)if(a[i].st<=x)
            res+= (min(x,a[i].ed) - a[i].st) / a[i].d + 1;
    	return res;
    }
    bool check(ll x,ll y)//判断当前区间是否有奇数个防具
    {
    	return ( S(y) - S(x-1) ) % 2 == 1;
    }
    int main()
    {
    	int T;scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%d",&n);
    		ll L = 1ll<<60,R = 0;
    		for(int i=1;i<=n;i++)
    		{
    			scanf("%lld%lld%lld",&a[i].st,&a[i].ed,&a[i].d);
    			L = min(L,a[i].st),R = max(R,a[i].ed);
    		}
    		if(!check(L,R))
    		{
    			printf("There's no weakness.\n");
    			continue;
    		}
    		ll l = L,r = R,p = 0;
    		while(l <= r)
    		{
    			ll mid=(l+r)>>1;
    			if(check(l,mid)) r=mid-1,p=mid;
    			else             l=mid+1;
    		}
    		printf("%lld %lld\n",p , S(p)-S(p-1) );
    	}
    	return 0;
    }
    

    位运算

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=2e5+5;
    struct node{ll st,ed,d;}a[N];
    
    int main()
    {
    	int T;scanf("%d",&T);
    	while(T--)
        {
    		int n;scanf("%d",&n);
    		ll p=0;
    		for(int i=1;i<=n;i++)
            {
    			ll st,ed,d;scanf("%lld%lld%lld",&st,&ed,&d);
    			a[i]={st,ed,d};
    			for(ll k=st;k<=ed;k+=d) p^=(k+1); //排除k=0的特殊情况
    		}
    		if(p==0)
            {
    		    printf("There's no weakness.\n");
    		    return 0;
    		}
    
    		p--;
    		ll num=0;
    		for(int i=1;i<=n;i++) if(a[i].st<=p && p<=a[i].ed)
                num+= ( (p-a[i].st)%a[i].d ==0 ) ;
    
    		printf("%lld %lld\n",p,num);
    	}
        return 0;
    }
    
    • 1

    *【二分|位运算】找有奇数个小球的位置[防线]

    信息

    ID
    1213
    时间
    1000ms
    内存
    64MiB
    难度
    4
    标签
    递交数
    63
    已通过
    31
    上传者