QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#500736#6730. CoolbitsPonyHexWA 1ms5668kbC++146.0kb2024-08-01 19:22:022024-08-01 19:22:03

Judging History

This is the latest submission verdict.

  • [2024-08-01 19:22:03]
  • Judged
  • Verdict: WA
  • Time: 1ms
  • Memory: 5668kb
  • [2024-08-01 19:22:02]
  • Submitted

answer

#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
#include<random>
#include <chrono>
using namespace std;
std::mt19937_64 rng((std::chrono::steady_clock::now().time_since_epoch().count()));
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define RND mt19937 rnd(0xab8d5f6);
#define time_while(time_while_val) while (((double)clock() - start) / clocks_per_sec < time_while_val)
//#define time_while(time_while_val) while ((double)clock() / clocks_per_sec < time_while_val)//弃
#define rep1(i, n) for(long long i = 1; i <= n; ++i)
#define rep0(i, n) for(long long i = 0; i <= n; ++i)
#define double long double
//#define int long long
//#define ll unsigned long long
#define lc u<<1
#define rc u<<1|1
#define endl "\n"
#define X first
#define Y second
typedef long long ll;
//typedef unsigned long long ull;
typedef pair<int, int> PII;
double PI = acos(-1.0);
const double eps = 1e-9;
const ll maxn = 2e5 + 5;
const ll maxm = 2e17;
const ll inf = 2147483647;
const ll mod = 1e9 + 7;
const int dx[] = { 1,0,-1,0,1,1,-1,-1 };//前4为邻
const int dy[] = { 0,-1,0,1,-1,1,-1,1 };

int gcd(int a, int b) {
    return b ? gcd(b, a % b) : a;
}

ll ksm(ll a, ll b) {
    ll ans = 1;
    ll base = a;
    while (b) {
        if (b & 1)ans = ans * base % mod;
        base = base * base % mod;
        b >>= 1;
    }
    return ans % mod;
}

ll getinv(ll a) {
    return ksm(a, mod - 2);
}

//dismyth
//警钟长鸣

/*2024/7/29
待补:cdq分治,三维偏序,平衡树->link cut tree*/
/*待补 324(包括f),310,313,315,317*///好多,但是每天得vp,强度得上去
/*306d,344d*/
//赛时多出,赛后少补
//vp一把


/*
struct cmp {
    bool operator()(pair<ll, ll> a, pair<ll, ll>  b) {
        return a.X > b.X;//表示小根堆
    }
};*/

//异或是可叠加的,所以异或是可求前缀和的


//vector<pair<ll, ll> >e;
ll e1[maxn];
ll e2[maxn];
//我们可以尝试把左界的二进制一次性都表示出来然后记录下来
//这样我们每次查询的时候就不会多次计算了
ll n;

inline bool check(ll l, ll r, ll val) {//对于元素val,检查是否在l到r中成立
    if (val > r)return false;
    //这是暴力的跑法,t了,很正常
    //所以我们不应该这样匹配
    //
    //if (r - l + 1 >= val)return true;
    //还是不够,
    //有了,wc我会了,我们判断左界距离这个状态差距有远,然后比较dis
    //就是,把l给扣下来
    //然后,看l的状态变成r需要的dis,r-l满足dis,则成立
    ll mid1 = val;
    ll mid2 = l;
    ll state = 0;
    ll upbound = 1;
    while (mid1) {
        state += (mid2 % 2) * upbound;
        upbound <<= 1;
        mid1 >>= 1;
        mid2 >>= 1;
    }
    //cout << upbound << " " << state << " " << val << endl;
    if (val >= state) {
        ll dis = val - state;
        if (dis <= (r - l))return true;
        else return false;
    }
    else {
        //寻找最小的操作数
        //懂了,这里不对
        //大概就是,
        
        ll newval = 0;
        ll dis = 0;
        ll ex = 1;
        ll mmd = val;
        ll mmmd = state;
        vector<ll>a;
        vector<ll>b;
        while (mmmd) {
            /*
            if (mmd % 2 == 1 && mmmd % 2 == 0) {
                dis += (ex);
            }*/
            a.push_back({ mmd % 2 });
            b.push_back({ mmmd % 2 });
            mmd >>= 1;
            mmmd >>= 1;
        }
        //将两个二进制记录下来,a是要求
        while (a.size()) {
            if (a.back() == 1 && b.back() == 0)break;
            a.pop_back();
            b.pop_back();
        }
        if (a.size()) {
            ll p1 = 0, p2 = 0;
            for (auto p = a.begin(),pp=b.begin(); p != a.end(); p++,pp++) {
                p1 += (*p) * ex;
                p2 += (*pp) * ex;
                ex <<= 1;
            }
            dis = p1 - p2;
        }

        //我说实话,这时候我想直接找最近的转移到的状态是否在范围内,并不好找,好找,但是我不好实现
        //不好不好
        //所以我们去
        //好好,是一样的,都不是很方便,还不如直接上
        //大体的思路就是从第一个位置,开始截取
        //那个位置就是,要求为1,但是确没有1的位置

        //尽力了,用尽手段,但是还是t了,感觉,优化
        //可以,我还能继续优化,做的更好

        if (dis <= (r - l))return true;
        else return false;
    }
    return false;
}

//RND;
void solve() {
    //有了,其实在check函数里,我们每次访问到左界,都进行了操作
    //那一步操作就是去匹配
    //我们没有必要每次都去找那些数
    //可以在进行check之前都处理出来

    cin >> n;
    ll mi = maxm;
    for (int i = 1; i <= n; i++) {
        //ll l, r; cin >> l >> r;
        cin >> e1[i] >> e2[i];
        mi = min(mi, e2[i]);
    }
    ll ans = 0;
    ll t = 32;
    //这个枚举我减少一点,能给我过吗
    ll bd = 0;
    while (mi) {
        mi >>= 1;
        bd++;
    }
    for (ll t = bd; t >= 0; t--) {
        ll md = ksm(2, t);//获取那个位置的数值
        ll mid = ans + md;//检查是否合法
        //首先,不能比右端点大
        bool f = 1;
        for (int i = 0; i < n; i++) {//对于每个区间,我们检查,当前ans是否合法
            //区间合法的条件,其一,至少区间右界应该大于等于当前的ans
            //f = check(e[i].X, e[i].Y, mid);
            f = check(e1[i], e2[i], mid);
            if (f == 0)break;
        }
        if (f) {
            ans = mid;
        }
    }
    cout << ans << endl;
    //e.clear();
    return;
}

signed main() {
    IOS;
    ll t = 1;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

/*致我已死的友人*/
/*PonyHex*/


Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 1ms
memory: 5668kb

input:

2
3
0 8
2 6
3 9
1
1 100

output:

0
0

result:

wrong answer 1st numbers differ - expected: '6', found: '0'