东华码蹄集第22周oj赛(splay ,小码哥们约见,子集统计,距离统计)

1 splay

县城里有n 个用地道相连的房子(编号为1~n),第i个只与第i-1和第i+1个相连。这时有m个消息依次传来:
1.若消息为D x:鬼子将×号房子摧毁了,地道被堵上。⒉.若消息为R︰村民们将鬼子上一个摧毁的房子修复了。3.若消息为o x:有一名士兵被围堵在×号房子中。
团长收到信息很紧张,他想知道每一个被围堵的士兵能够到达的房子有几个。
在这里插入图片描述

 思路:每次从查询就是找出破坏房屋序列在有序情况下第一个大于查询房屋
 的值,最后一个小于查询房屋序号的值,维护两个破坏房屋的map,第一个
 存正值,第二个存负值,随便搞一搞就出来了

代码如下

/*
 * @Author: 晚乔最美
 * @Date: 2022-10-25 19:41:17 
 * @Last Modified by: 晚乔最美
 * @Last Modified time: 2022-10-25 20:01:13
 */

#include<bits/stdc++.h>
#include<bitset>
#include<unordered_map>
#define pb push_back
#define bp __builtin_popcount
#define TIME cout << "RuningTime: " << clock() << "ms\n", 0
#define ls x<<1
#define rs x<<1|1
using namespace std;
typedef  long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
const int MOD=9901;
const int mod = 1e9+7;
const double PI=3.14;
int lowbit(int x){return x&-x;}
ll gcd(ll x, ll y){ return y == 0 ? x : gcd(y, x%y); }
ll lcm(ll x, ll y){ return x / gcd(x, y)*y; }
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % MOD; b >>= 1; t = (t*t) % MOD; }return r; }
inline ll fpow(ll a, ll b,ll p){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % p; b >>= 1; t = (t*t) % p; }return r; }

inline int read()
{
	int x = 0,f = 1;
	char ch = getchar();
	while (ch < '0' || ch>'9')
	{
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9')
	{
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x * f;
}


int main() {

    int n, m;
    cin >> n >> m;
    map<int, int> mmp1;
    map<int,int> mmp2;
    char ch;
    int x;
    stack<int> st;
    for (int i = 1; i <= m;i++)
    {
        
        cin >> ch;
        if(ch=='D')
        {
            cin >> x;
            mmp1[x]++;
            mmp2[-x]++;
            st.push(x);
        }
        else if(ch=='Q')
        {
            cin >> x;
            if(mmp1.count(x))
            {
                cout << 0 << endl;
                continue;
            }
            int bg = 0, en = n+1;
            auto iter = mmp1.upper_bound(x);
            if(iter!=mmp1.end())
                en = iter->first;
             iter = mmp2.upper_bound(-x);
            if(iter!=mmp2.end())
                bg = -iter->first;
           // cout << -bg << " " << en << endl;
            cout << en - bg - 1 << endl;
        }
        else{

            if(st.empty())
                continue;
            int la = st.top();
            st.pop();
            mmp1.erase(la);
            mmp2.erase(-la);
        }
        
    }


    //system("pause");
        return 0;
}

/*
7 9
Q 3
Q 6
Q 5
Q 1
Q 2
R
Q 3
R
Q 4


7 7 7 7 7 7 7
*/

2 小码哥们约见

有两个小码哥住在地球赤道上,他们突然想见一面,他们约定都向西走直到相见为止。相见的条件是同一时间走在同一位置。假设以赤道上某一点为原点。1号小码哥住在x处,一步能走m米;2号小码哥住在y处,一步能走n米。两个小码哥总是同时抬脚同时脚落地,赤道长L米。现在请问他们需要走多少步才会见面。

     思路:从题中信息容易得到其实就是让我们求一个方程 
     m*k-n*k=c*l+x-y转换一下可以得到
     其实就是求
     (m-n)*k-c*l=x-y是k,c是否有解,求出最小的k的解
     
     容易想到,exgcd(拓展欧几里) 得随便套进来搞搞就行了,
     不会exgcd自行百度

代码如下

/*
 * @Author: 晚乔最美 
 * @Date: 2022-10-25 15:48:37 
 * @Last Modified by:   晚乔最美 
 * @Last Modified time: 2022-10-25 16:19:34 
 */
#include<bits/stdc++.h>
#include<bitset>
#include<unordered_map>
#define pb push_back
#define bp __builtin_popcount
#define TIME cout << "RuningTime: " << clock() << "ms\n", 0
#define ls x<<1
#define rs x<<1|1
using namespace std;
typedef  long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
const int MOD=9901;
const int mod = 1e9+7;
const double PI=3.14;
int lowbit(int x){return x&-x;}
ll gcd(ll x, ll y){ return y == 0 ? x : gcd(y, x%y); }
ll lcm(ll x, ll y){ return x / gcd(x, y)*y; }
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % MOD; b >>= 1; t = (t*t) % MOD; }return r; }
inline ll fpow(ll a, ll b,ll p){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % p; b >>= 1; t = (t*t) % p; }return r; }
priority_queue<int, vector<int>, greater<int> > q;

ll e_gcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x = 1;
        y = 0;
        return a;
    }
    ll ans = e_gcd(b, a % b, x, y);

    ll temp = x;

    x = y;

    y = temp - a / b * y;

    return ans;

}
 
ll cal(ll a,ll b,ll c)
{
    ll x, y;
    ll gcd = e_gcd(a, b, x, y);

    if(c%gcd!=0) return -1;

    x *= c / gcd;

    b /= gcd;
    if(b<0) b=-b;
    ll ans = x % b;
    if(ans<=0)
        ans += b;
    return ans;
}


int main()
{
// x+mk-y-nk=cl  ->(m-n)k-cl=y-x  求满足条件的二元一次方程的K的最小正整数解
    int X,Y,m,n,l,x,y;
   cin>>X>>Y>>m>>n>>l;


   ll ans=cal(m-n,l,Y-X);
     
	cout<<ans<<endl;
    

        // system("pause");

        return 0;
}





3 子集统计

给定两个长度为n的二进制数A,B,你需要统计长度为n 的二进制数C的数量,满足以下两个条件:
A and C = C
Cand B =B
其中and为按位与符号。例如
10011 and 11000= 10000,11111 and 00000= 00000

在这里插入图片描述
简单题,自己看代码吧

/*
 * @Author: 晚乔最美 
 * @Date: 2022-10-25 16:40:37 
 * @Last Modified by:   晚乔最美 
 * @Last Modified time: 2022-10-25 16:53:34 
 */
#include<bits/stdc++.h>
#include<bitset>
#include<unordered_map>
#define pb push_back
#define bp __builtin_popcount
#define TIME cout << "RuningTime: " << clock() << "ms\n", 0
#define ls x<<1
#define rs x<<1|1
using namespace std;
typedef  long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
const int MOD=9901;
const int mod = 1e9+7;
const double PI=3.14;
int lowbit(int x){return x&-x;}
ll gcd(ll x, ll y){ return y == 0 ? x : gcd(y, x%y); }
ll lcm(ll x, ll y){ return x / gcd(x, y)*y; }
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % MOD; b >>= 1; t = (t*t) % MOD; }return r; }
inline ll fpow(ll a, ll b,ll p){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % p; b >>= 1; t = (t*t) % p; }return r; }

int main()
{

   // cout << (46 & (32 + 14)) << endl;
    //cout << (46 & 28) << endl;
    string str;
    cin >> str;
    string st;
    cin >> st;
    int len = str.length();
    int num1 = 0, num2 = 0;
    for (int i = 0; i < str.length();i++)
    {
        num1 = num1 * 2 + str[i] - '0';
    }

    for (int i = 0; i < st.length();i++)
    {
        num2 = num2 * 2 + st[i] - '0';
    }
        int cvr = 1 << (len+1);
        //int cur = 1 << (len-1);

        int ans = 0;
        for (int i = 0; i < cvr; i++)
        {
        
            if ((num1&i)==i&&(i&num2)==num2)
                 {
                    // cout << i << endl;
                     ans++;
                 }
        }
    

    cout << ans << endl;

    //system("pause");

    return 0;
}

4 距离统计

给你一个长度为 n 的整数数组a1, a2,… . , an。定义数组的和谐值为数组中任意两个元素的差的符号乘距离的和。即
H(a)=>l<i<j<n sgn(a; - a;)i一jl
其中
1,a > 0
sgn(z)=〈0,=0
-1, c <0
请你计算一下给定的整数数组的和谐值吧。
在这里插入图片描述
简单题,自行看代码

/*
 * @Author: 晚乔最美 
 * @Date: 2022-10-25 16:40:37 
 * @Last Modified by:   晚乔最美 
 * @Last Modified time: 2022-10-25 16:53:34 
 */
#include<bits/stdc++.h>
#include<bitset>
#include<unordered_map>
#define pb push_back
#define bp __builtin_popcount
#define TIME cout << "RuningTime: " << clock() << "ms\n", 0
#define ls x<<1
#define rs x<<1|1
using namespace std;
typedef  long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
const int MOD=9901;
const int mod = 1e9+7;
const double PI=3.14;
int lowbit(int x){return x&-x;}
ll gcd(ll x, ll y){ return y == 0 ? x : gcd(y, x%y); }
ll lcm(ll x, ll y){ return x / gcd(x, y)*y; }
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % MOD; b >>= 1; t = (t*t) % MOD; }return r; }
inline ll fpow(ll a, ll b,ll p){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % p; b >>= 1; t = (t*t) % p; }return r; }
int f[maxn];
int sng(int x)
{
    if(x==0)
        return x;
    return x > 0 ? 1 : -1;
}
int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n;i++)
        cin >> f[i];
    int ans = 0;
    for (int i = 1; i <= n;i++)
        for (int j = 1; j < i;j++)
        {
            ans = ans + sng(f[j] - f[i]) * abs(i - j);
        }

    cout << ans << endl;

    //system("pause");

    return 0;
}
  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值