QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#500600 | #6730. Coolbits | PonyHex | TL | 0ms | 3644kb | C++14 | 4.7kb | 2024-08-01 16:05:25 | 2024-08-01 16:05:26 |
Judging History
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 n;
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 dis = 0;
ll ex = 1;
ll mmd = val;
ll mmmd = state;
while (mmd) {
if (mmd % 2 == 1 && mmmd % 2 == 0) {
dis += (ex);
}
mmd >> 1;
mmmd >>= 1;
ex <<= 1;
}
if (dis <= (r - l))return true;
else return false;
}
return false;
}
//RND;
void solve() {
//看不懂,敲一遍就懂了
//
//在此之前,思考一下,我们先确定放1的最高位
//然后我们在每个区间确定好放置最高位的同时,
///不会,怎么根本看不懂啊
//很能写,我不能,所以要练
//有想法,就去做,我们每次贪心选取位置来放置
cin >> n;
ll mi = maxm;
for (int i = 1; i <= n; i++) {
ll l, r; cin >> l >> r;
mi = min(mi, r);
e.push_back({ l,r });
}
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);
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: 100
Accepted
time: 0ms
memory: 3644kb
input:
2 3 0 8 2 6 3 9 1 1 100
output:
6 100
result:
ok 2 number(s): "6 100"
Test #2:
score: -100
Time Limit Exceeded
input:
1117 74 234256176 451122435 614716780 701954053 31102604 284818525 528763990 809400397 40637446 612671528 329403504 936190213 112402633 729525189 248142852 481053286 30877745 700834811 529884578 749041634 146522084 758550567 934650972 996096650 538751855 856147351 170918541 975066425 253153230 35361...