Codeforces Round #626 (Div. 2)

A
这个似乎出过一遍了?选一个偶数或者两个奇数。

B
题意:
给你 n n 个数 a 1 , a 2 , a 3 , a 4 . . . . . . a n a_1,a_2,a_3,a_4......a_n
再给你 m m 个数 b 1 , b 2 . . . . . b m b_1,b_2.....b_m
有一个矩形 n m n\cdot m 的矩形C, C i , j = a i b j C_{i,j}=a_i\cdot b_j ,且 a , b a,b 中的数不是0,就是1,所以C中也是不是零就是1。
现在给你一个 k k ,让你输出C中面积为 k k 的矩形个数。
思路:
这个题目怎么说呢,说好想也好像,说不好想也不好想。。。。
首先,因为 a , b a,b 中不是零就是1,所以C中为1的区域肯定是矩形,且大小为 a a 中连续1的个数 * b b 中连续1的个数,有疑问可以画一下,到这儿还是比较好想的。然后接下来是重点。

假设a产生的连续的段为 x 1 , x 2 . . . . . x c n t 1 x_1,x_2.....x_{cnt1}
b产生连续的段为 y 1 , y 2 , y 3 . . . . y c n t 2 y_1,y_2,y_3....y_{cnt2}
这可以构成 c n t 1 c n t 2 cnt1\cdot cnt2 个矩形。
我们先按正解来,对于面积 k k 的矩形,我们枚举边长, < x , y > <x,y>
然后提前预处理好 a a 中段对x的贡献,每一个为 x i x + 1 x_i-x+1 ;同理 y y 也是这样。
答案就是 i = 1 c n t 1 ( x i x + 1 ) i = 1 c n t 2 ( y i y + 1 ) \sum\limits_{i=1}^{cnt1}(x_i-x+1)\cdot \sum\limits_{i=1}^{cnt2}(y_i-y+1) 。对于枚举边长,复杂度 O ( N ) O(N) ,预处理时间复杂度也是 O ( N ) O(N)
这样想似乎这个题目也就这样。。。。

但在比赛中我没想到直接枚举面积为 k k 的矩形边长,而是枚举的 a b a*b 中可以产生的矩形,正如上文所说, a , b a,b 可以构成矩形为 c n t 1 c n t 2 cnt1\cdot cnt2 个。对于每个矩形我们算面积为 k k 的贡献,怎么算呢?对于每个矩形 x i y i x_i\cdot y_i ,也是枚举边长,不过是枚举 x i x_i 的边长,看其是否可以构成面积为 k k 的矩形,这里假设枚举 x i x_i 的边长为 x x ,那么 y = k / x y=k/x 。那么 x i y i x_i\cdot y_i 可以产生 < x , y > <x,y> 的贡献为 ( x i x + 1 ) ( y i y + 1 ) (x_i-x+1)\cdot (y_i-y+1) 。其中 x x 的范围 [ 1 , x i ] [1,x_i] 。我们不断累加贡献,也能得到贡献,但这样随机数据尚可,但最坏会被卡成 n 2 n^2 。值的一提的是我一开始看错范围以为4000。。。一直Wa和T,后经ZHJ提醒,数组开到40000,竟然以998ms的时间卡过,虽说后来重测被卡掉,但是这也不失是一件趣事。

赛后我以我的思路印证题解中代码,一直对上面正解中预处理边长累加那儿有疑惑,这很矛盾,在我的思路中,是枚举矩形然后对于这个矩形,在枚举边长,贡献是相乘后在相加,而题解中是相加后在相乘,这可能对别人来说很容易想透的,但对于我而言,这有点无法接受,人和人之间的思维方式真的有差别。

我按我的方式进行了思考,发现这两种思路是殊途同归的。我将用我的思路来解释正解。

假设 a a 数组又连续段 a 1 , a 2 a_1,a_2 ,b数组有连续段 b 1 , b 2 b_1,b_2
我们可以构造 a 1 a_1 x b 1 b_1 , a 1 a_1 x b 2 b_2 , a 2 a_2 x b 1 b_1 , a 2 a_2 x b 2 b_2 ,四个矩形,原来是对每个矩形枚举边会超时,现在是对面积为 k k 的矩形我们找边 < x , y > <x,y>
然后这四个矩形对其产生的贡献为
( a 1 x + 1 ) ( b 1 y + 1 ) + ( a 1 x + 1 ) ( b 2 y + 1 ) + ( a 2 x + 1 ) ( b 1 y + 1 ) + ( a 2 x + 1 ) ( b 2 y + 1 ) (a_1-x+1)\cdot (b_1-y+1)+(a_1-x+1)\cdot (b_2-y+1)+(a_2-x+1)\cdot(b_1-y+1)+(a_2-x+1)\cdot (b_2-y+1)
我们对上述式子进行提取公因式得
( ( a 1 x + 1 ) + ( a 2 x + 1 ) ) ( ( b 1 y + 1 ) + ( b 2 y + 1 ) ) ((a_1-x+1)+(a_2-x+1))\cdot ((b_1-y+1)+(b_2-y+1))
这个式子就是说对于边 < x , y > <x,y> 结果是,a中所有段对 x x 产生的贡献相加 乘以 b中所有段对 y y 产生贡献的累加,这里所说的贡献可以当做产生多少 x x ,产生多少 y y

bool a[N],b[N];
ll q[N],p[N];
void init(int n,int m){ 
    int cnt1(0),cnt2(0);
    rep(i,1,n){
        if(a[i] == 0){
            for(int j =1 ;j <= cnt1;++j){
                q[j] += cnt1 - j + 1;
            }
            cnt1 = 0;
        }
        else cnt1 ++;
    }
    if(cnt1){
        rep(j,1,cnt1) q[j] += cnt1 - j + 1;
    } 
    rep(i,1,m){
        if(b[i] == 0) {
            for(int j = 1;j <= cnt2;++j) p[j] += cnt2 - j + 1;
            cnt2 = 0;
        }
        else cnt2++;
    }
    if(cnt2){
        rep(j,1,cnt2) p[j] += cnt2 - j + 1;
    }
}
int main(){
    int n = read(),m = read(),k =read();
    rep(i,1,n) a[i] = read();
    rep(i,1,m) b[i] = read();
    init(n,m); 
    ll ans = 0;
    for(int i = 1;i <= n;++i){
        if(k % i == 0){
            int x = i,y = k/i;
            if(y <= m) ans += q[x]*p[y];
        }
    }
    cout<< ans;
}

C
题意:
就是括号匹配,但是现在的问题是你可以通过对任意 [ l , r ] [l,r] 排序,代价是这段的长度,来使的括号匹配。
思路:
首先就是若左右括号不等则一定不能匹配,否则一定可以。
我们设一个栈,然后从头遍历每个字符。
我们知道括号匹配的形式是 ( ) () ,所以我们考虑当前字符是否是’(’,如果是的话,看栈顶元素是否是’)’,如果是的话,这说明可以将这两个字符排序可以正确匹配,所以我们将 a n s + = 2 ans+=2 ,并且删除栈顶元素;不是的话就将’(‘入栈。
如果当前元素是’)’ ,看栈顶是否是’('是的话就删除栈顶元素;否则入栈。
我们发现这样的匹配思路并没有错,而且代码还很好写。具体的怎么的正确我曾尝试证明,但是失败了。

stack<char> st;
int main(){
    int n = read();
    string s;
    cin >> s;
    int l = s.size();
    int cnt1(0),cnt2(0);
    rep(i,0,l-1){
        if(s[i]=='(') cnt1++;
        else cnt2++;
    }
    if(cnt1!=cnt2) return puts("-1"),0;
    int ans = 0;
    rep(i,0,l-1){
       if(s[i] =='('){
           if(st.size()&&st.top()==')'){st.pop();ans+=2;}
           else st.push('(');
       }
       else if(st.size()&&st.top()=='(') st.pop();
       else st.push(s[i]);
    }
    cout <<ans;
}

D

发布了603 篇原创文章 · 获赞 34 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_43408238/article/details/104734754
今日推荐