当前位置: 首页 > news >正文

NOIP2024 遗失的赋值

NOIP2024 遗失的赋值

给定一堆一元限制,问有多少种二元限制的方案,使得至少存在一种对 \(x_{1 \sim n}\) 赋值方法满足所有限制。

观察数据发现如下性质:

1、一元限制的作用:对于 \(x_{c_j} = d_j\),当 \(a_{c_j} = d_j\) 是,强制 \(x_{c_j + 1} = b_{c_{j}}\)

2、当 \(m = 1\) 时,答案是 \(v^{2n - 2}\)。因为模拟后可以发现这个限制没有什么用。

3、当没有一元限制干扰时,尽量按 \(x_i \ne a_i\) 填,限制最宽松(即需要满足的二元限制最少)。

4、最后一个一元限制不做限制。两个一元限制隔得较远,相当于在传递限制。

现在我们来考虑 \(m = 2\) 的情况。

一开始我以为这个贡献与一元限制的距离无关,就直接用相邻的计算方法算了所有,即 \([(v - 1) \times v + 1] ^ {len}\)\(len\) 就是两个一元限制的距离。结果后来发现,对答案分解质因数后,里面死活会有一些根本不会在我的式子里出现的系数,这说明要么是不受限制的贡献统计有问题,要么是受限制的贡献统计有问题。中途犹豫了很久以为是不受限制的部分出错了,最后终于拿下性子手搓了一个距离为 \(2\) 的样例,发现贡献长得非常丑陋:

\[(v - 1)v \times v^2 + v \times ((v -1)v \times v + v \times ((v - 1)v + 1) ) \]

解释一下,其实容易发现这个式子有明显的递归特性,当下一个点不是另一个一元限制时,当前点裂成两种情况:

情况一:使 \(a_i\) 摆脱上一个一元限制,则 \(a_i\)\(v - 1\) 种填法,\(b_i\) 就可以随便填了,故贡献系数使 \((v - 1)v\),那么下一个位置 \(a, b\) 都可以随便填,贡献是 \(v^2\)

情况二:使 \(a_i\) 保持限制,则 \(a_i\)\(1\) 种填法,\(b_i\)\(v\) 种填法,然后情况继续分裂下去。直到最后一个保持限制的位置,只有 \(1\) 的贡献。(就是上述式子最后那个 \(1\))。

那么距离更大的情况,就继续递归就可以了。

经过一番艰苦的化简,发现:

距离为 \(1\)\(v^4 - v^2 + v^1\)

距离为 \(2\)\(v^6 - v^3 + v^2\)

\(\vdots\)

距离为 \(i\)\(v^{2(i + 1)} - v^{i + 1} + v^i\)

于是问题就变得简单了,只需要分别处理每两个一元限制的贡献,最后乘起来即可。

时间复杂度 \(O(Tm \log n)\)

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l); i <= (r); ++ i)
#define G(i,r,l) for(int i(r); i >= (l); -- i)
#define int ll
using namespace std;
using ll = long long;
const int mod = 1e9 + 7;
const int N = 2e5;
int cnt = 0; 
int quickmod(int x, int y){int ret = 1;while(y){if(y & 1) ret = ret * x % mod;x = x * x % mod;y >>= 1;}return ret;
}
int n, m, v, T, tt;
int a[N];
map<int, int>mp;
namespace task{void Main(){assert(mp[0] == 0);cin >> n >> m >> v;int flag = 1;int tot = 0;int ret = 1;F(i, 1, m){int c, d;cin >> c >> d;if(mp[c] > 0){if(mp[c] != d) flag = 0;}else {mp[c] = d; ++ tot; }a[i] = c;}if(!flag){cout << "0\n";}else{int r = m;sort(a + 1, a + r + 1);r = unique(a + 1, a + r + 1) - a - 1;F(i, 2, r){int len = a[i] - a[i - 1] - 1;int tmp = (quickmod(v, 2 * len + 2) - quickmod(v, len + 1) + quickmod(v, len)) % mod;ret = ret * tmp % mod;}ret = ret * quickmod(v * v % mod, a[1] - 1) % mod;ret = ret * quickmod(v * v % mod, n - a[r]) % mod;cout << (ret + mod) % mod << '\n';}mp.clear();}
} 
signed main(){
//	freopen("assign.in", "r", stdin);
//	freopen("assign.out", "w", stdout);ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);cin >> T; tt = T;while(T --) task::Main();return fflush(0), 0;
}
http://www.sczhlp.com/news/55689/

相关文章:

  • 右移运算符 () a n 表示将a的二进制位向右移动n位 右移相当于除以2^n(对于正数) 1 2 = 1 4 = 0(整数除法)
  • 在婚恋网站做销售好吗网站开发一年费用总计
  • 合肥做网站域名的公司广东 品牌网站建设
  • 有哪些网站可以做海报织梦建网站
  • 搜索引擎网站网站建设与推广的实训报告
  • 加强司法机关网站建设如何找外贸公司合作
  • 苏州市网站建设服务中装装饰工程有限公司
  • 建设网站需要购买虚拟主机吗如何制作网页二维码
  • 新建的网站怎么上首页国际军事新闻视频直播
  • php建站软件哪个好angularjs网站模板
  • 手机钓鱼网站免费制作dw网页制作破解版
  • 网站功能配置wordpress keywords 用逗号 区分关键字
  • day 313233 MCP快速入门实战
  • Python 的内置函数 all() 来检查一个可迭代对象中的所有元素是否都为真
  • 网站充值这么做苏州网站建设制度
  • 做好一个网站需要多久哈尔滨公共资源信息网
  • 网站推广软件免费wordpress中小型门户
  • 网站建设都用哪个好西部数码网站管理助手 没有d盘
  • 青岛网站建设seo优化制作设计网站推广业务
  • 东莞seo网站关键词优优化企业门户网站建设市场
  • 有哪些做平面设计好素材网站有哪些石狮网站建设价格
  • 最便宜做网站珠海百度seo
  • 自己电脑做网站需要什么设备自考大专报名官网入口
  • 建立网站的请示网站上传后
  • 水木网站建设制作图
  • 网站焦点图素材网站推广互联网推广
  • 甘孜州建设局网站兰州网站建设小程序
  • 网站主题模板下载自己做一元夺宝网站
  • P5088 矩形
  • 2025-08-31 antd的menu垂直菜单示例无法渲染出来?==》没有引用SubMenu组件