随笔 - 164  文章 - 0  评论 - 4  阅读 - 9769

2023牛客多校第九场 - E I

比赛地址:传送门
赛时实际上就过了签到题,呜呜~
E 思维题
I 思维题

E Puzzle: Square Jam

题意

思路
每次取最小的边,辗转相减即可

代码

void solve(){
int n, m;
cin >> n >> m;
vector<tuple<int, int, int>> ans;
ll res = n * m, x = 0, y = 0, l;
while(res){
l = min(n - x, m - y);
ans.push_back(make_tuple(x, y, l));
if(n - x < m - y){
y += n - x;
}else{
x += m - y;
}
res = (n - x) * (m - y);
}
cout << "YES\n" << ans.size() << '\n';
for(auto [x, y, z] : ans){
cout << x <<' ' << y << ' ' << z << '\n';
}
return ;
}

I Non-Puzzle: Segment Pair

题意
给定 n 对区间,你可以在每一对区间里面任选一个区间,若这种选法所得的 n 个区间的交集不为空,那么这就是一个合法的选择区间的方式
问你选择合法区间的方式的个数模 109+7

思路
思路来源

考虑所有点对于答案的贡献,对于每个区间仅让一个点对答案产生贡献
先计算出所有合法点对于答案的总贡献,再将所有给定区间的左端点均 + 1,再计算修改后的区间的赘余贡献,用前面算出的总贡献减去赘余贡献即为最终的答案

利用 dsu 压缩路径,利用差分数组统计重复选择

详见代码

代码

//>>>Qiansui
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x, y, sizeof(x))
#define debug(x) cout << #x << " = " << x << '\n'
#define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << '\n'
//#define int long long
using namespace std;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef pair<double, double> pdd;
/*
*/
const int maxm = 5e5 + 5, inf = 0x3f3f3f3f, mod = 1e9 + 7;
int n;
vector<array<int, 4>> seg(maxm);
ll pw2[maxm];
void pre(){
pw2[0] = 1;
for(int i = 1; i < maxm; ++ i){
pw2[i] = pw2[i - 1] * 2 % mod;
}
return ;
}
struct DSU{
int num;
vector<int> fa;
DSU(int x = maxm) : num(x), fa(x + 1){
for(int i = 0; i <= x; ++ i) fa[i] = i;
}
int findfa(int x){//迭代实现,不压缩路径,用于数范围大时
while (x != fa[x]) x = fa[x] = fa[fa[x]];
return x;
}
// int findfa(int x){ return fa[x] == x ? x : fa[x] = findfa(fa[x]); }//递归实现,压缩路径
void merge(int u, int v){
fa[findfa(u)] = findfa(v); return ;
}
bool same(int u, int v){ return findfa(u) == findfa(v); }
};
ll calc(){
vector<bool> ok(maxm, true);
vector<int> cnt(maxm, 0);
DSU dsu(maxm);
for(int i = 0; i < n; ++ i){
auto &[l1, r1, l2, r2] = seg[i];
for(int j = dsu.findfa(1); j < l1; j = dsu.findfa(j)){
ok[j] = 0;
dsu.merge(j, j + 1);
}
for(int j = dsu.findfa(max(r1, r2) + 1); j <= 5e5; j = dsu.findfa(j)){
ok[j] = 0;
dsu.merge(j, j + 1);
}
if(l2 > r1){
for(int j = dsu.findfa(r1 + 1); j < l2; j = dsu.findfa(j)){
ok[j] = 0;
dsu.merge(j, j + 1);
}
}
int ml = max(l1, l2), nr = min(r1, r2);
if(ml <= nr){
++ cnt[ml]; -- cnt[nr + 1];
}
}
for(int i = 1; i <= 5e5; ++ i) cnt[i] += cnt[i - 1];
ll res = 0;
for(int i = 1; i <= 5e5; ++ i){
if(ok[i]){
res += pw2[cnt[i]];
res %= mod;
}
}
return res;
}
void solve(){
pre();
cin >> n;
for(int i = 0; i < n; ++ i){
auto &[l1, r1, l2, r2] = seg[i];
cin >> l1 >> r1 >> l2 >> r2;
if(l1 > l2){
swap(l1, l2);
swap(r1, r2);
}
}
ll ans = calc();
for(int i = 0; i < n; ++ i){
auto &[l1, r1, l2, r2] = seg[i];
++ l1; ++ l2;
}
ans = (mod + ans - calc()) % mod;
cout << ans << '\n';
return ;
}
signed main(){
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
// cin >> _;
while(_ --){
solve();
}
return 0;
}
posted on   Qiansui  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示