zoukankan      html  css  js  c++  java
  • 题解-CF809C Find a car[*easy]

    题解区里面写的都是数位 (dp),蒟蒻来一个奇怪的做法。

    通过打表发现这是一个分形,然后可以发现 (a_{i, j} = (i - 1) oplus (j - 1) + 1) (蒟蒻也不知道怎么证明)

    考虑把这个矩阵转化为前缀和。现在我们要求的是 (f(x, y) = sumlimits_{i = 0}^{x-1} sumlimits_{j = 0}^{y-1} [i oplus j + 1 le t] i oplus j + 1)

    这个东西可以用类似于二维树状数组的东西来搞。把这个前缀和分成很多个矩阵,每个矩阵都是 ((x - lowbit(x), x), (y - lowbit(y), y)) 的形式。

    我们让 (lowbit(x) ge lowbit(y))

    发现对于每一个区间内的 (y) 坐标,那么他们异或上 (x) 坐标区间后的值的集合是固定的!让 (t = (x - lowbit(x) ) oplus (y - lowbit(y))),那么 (y) 坐标异或上 (x) 坐标区间后的值是一段区间,区间都是 ([t, t + lowbit(x))) (注意之后还要 (+1))

    时间复杂度 (Theta(T log r_1 log r_2))

    代码很好写:

    #include<bits/stdc++.h>
    #define L(i, j, k) for(int i = j, i##E = k; i <= i##E; i++)
    #define R(i, j, k) for(int i = j, i##E = k; i >= i##E; i--)
    #define ll long long
    #define ull unsigned long long
    #define db double
    #define pii pair<int, int>
    #define mkp make_pair
    using namespace std;
    const int N = 1e3 + 7;
    const int mod = 1e9 + 7;
    inline int read() {
    	int x = 0, f = 1; char ch = getchar();
    	while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); }
    	while('0' <= ch && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
    	return x * f;
    }
    int n, m, T;
    int Sum(int l, int r) {
    	return (ll) (r - l + 1) * (l + r) / 2 % mod;
    }
    int Get(int l1, int r1, int l2, int r2, int k) {
    	if(r1 - l1 < r2 - l2) swap(l1, l2), swap(r1, r2);
    	int mn = (l1 ^ l2), len = r1 - l1;
    	mn ^= (mn & (len - 1));
    	if(k <= mn) return 0;
    	return (ll) (r2 - l2) * Sum(mn + 1, min(k, mn + len)) % mod;
    }
    int work(int x, int y, int k) {
    	int res = 0;
    	for(int i = x; i; i -= (i & -i)) for(int j = y; j; j -= (j & -j)) (res += Get(i - (i & -i), i, j - (j & -j), j, k)) %= mod;
    	return res;
    }
    void Main() {
    	int l1 = read(), l2 = read(), r1 = read(), r2 = read(), k = read();
    	printf("%d
    ", ((work(r1, r2, k) - work(l1 - 1, r2, k) - work(r1, l2 - 1, k)
    	 + work(l1 - 1, l2 - 1, k)) % mod + mod) % mod);
    }
    int main() {
    	T = read();
    	while(T--) Main();
    	return 0;
    }
    
  • 相关阅读:
    个人收藏的flex特效网址【经典中的极品】
    JavaWEB开发国际化
    Java实现寻找和为定值的多个数
    Java实现寻找和为定值的多个数
    Java实现寻找和为定值的多个数
    Java实现寻找和为定值的多个数
    Java实现二进制幂
    Java实现二进制幂
    Java实现二进制幂
    Java实现二进制幂
  • 原文地址:https://www.cnblogs.com/zkyJuruo/p/14356706.html
Copyright © 2011-2022 走看看