Codeforces Round # 515 (part of the solution to a problem) (Div. 3)

Topic Link

 

A. Vova and Train

The meaning of problems: a given interval [1, L], an interval [l, r], given a v. Q in [1, L] There are not within [l, r] v is the number of a divisor number.

Solution: first find the total interval divisor v, minus [l, r] divisor.

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	cin>>n;
	while(n--)
	{
		long long L,v,l,r,ans=0;
		cin>>L>>v>>l>>r;
		ans=L/v-r/v+(l-1)/v;
		cout<<ans<<'\n';
	}
	return 0;
 } 

 

 

B. Heaters

Meaning of the questions: Vova house is a one-dimensional coordinate system, n-room, the room represents a heater, to give [pos-r + 1; pos + r-1] for a range of room heating. r is a given, and is the same for each heater. Q. How to choose the least open heater, it can make all the room can be heated to.

Solution: simple greed plus violence. First, when I chose a heated room, the next room of the range is selected, [i + 1, i + r * 2-1]. Since each of the rooms has a heater, the heating range can cover about, the best choice is the middle of the room heating two sections do not overlap, so that the optimal solution is to select the next segment of the [i + 1 room , i + r * 2-1] traversed back to front. Selecting a first range of rooms is [1, r].

 

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2020;
int a[maxn];
int main()
{
	int n,r;
	cin>>n>>r;
	for(int i=1;i<=n;i++) cin>>a[i];
	
	int cur=0;//之前选择的房间位置
	
	int i=r;//能够贪心选择最远房间的位置 
	
	int flag,ans=0;
	while(1){
		flag=1;
		for(int j=i;j>cur&&flag;--j){
			if(a[j]) {
		    	i=j+2*r-1;//能够贪心选择最远房间的位置 
				ans++;
				flag=0;
				cur=j;//保存现在选择房间的位置	
			}
		}
		if(flag) break;//没有找到满足条件的房间 
		
		if(cur+r-1>=n) break;//已经覆盖了所有房间 
		
		if(i>n) i=n;
	}
	printf("%d\n",flag==1?-1:ans);
}

 

 

C. Books Queries

Meaning of the questions: There is a two-way queue. L represents the left side of this element into the queue, R representative of this element into the right. ? On behalf of many elements can at least make a query to delete this element in the leftmost or rightmost queue queue.

Solution: start with a two-way queue directly to analog, but the scope of the data too large T. Behind the carefully thought for a moment, every time I add a time element to the queue, he must queue leftmost or rightmost section, when I check the element of time is not as long as the back relatively newly added and how many L how many R just fine.

For example, I want to query elements L1

L1 is assumed to be added when the situation is such that the queue L1 LLRRR; left three discharge queue, the queue three put right.

Assume that when I have to find a queue has been updated into a LL L1 LLRRRR L1 time.

If you want to make L1 become the leftmost element, that is, the number of elements in the left section of the query, add minus the number of elements in L1 time left. That is, 5-3 = 2.

If you want to make L1 become the extreme right elements, and that is the right number of elements of the query, plus add L1 is the number -1 left elements. I.e. 4+ (3-1) = 6.

How quickly find that this element is added in which the time for it. We can define an array pos [maxn]. Another pos [L1] = i, can save the position of the element.

 

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6;
int pos[maxn];
struct node{
	int l,r;//保存此时放队列左边的个数,以及放右边的个数 
	int id;//1表示这个元素放左边,2表示这个元素放右边 
}e[maxn];
int main()
{
	int n,l=0,r=0;
	cin>>n;
	for(int i=1;i<=n;i++){
		getchar();
		char c;int x;
		cin>>c>>x;
		
		if(c=='L') l++,e[i].id=1;
		if(c=='R') r++,e[i].id=2;
		
		if(c=='?'){
			int ans=0;
			if(e[pos[x]].id==1){
				ans = min(l-e[pos[x]].l,r+e[pos[x]].l-1);
			}
			if(e[pos[x]].id==2){
				ans = min(r-e[pos[x]].r,l+e[pos[x]].r-1);
			}
			cout<<ans<<endl;
			continue;
		}
		
		e[i].l=l;e[i].r=r;
		
		pos[x]=i;//保存这个元素在结构体的位置 
	}
}

 

 

 

E. Binary Numbers AND Sum

This e knock simple question, no wonder xls ten minutes seconds, and regret when the game did not look at this problem qwq.

Meaning of the questions: give you two binary numbers is 01 strings, a string does not move, b each string right one. The results of each string and a string b & obtained after the movement after together until b is 0;

Solution: prefix + fast and power. Initially I thought it was a problem of large numbers, and then think of the position of parity and the like. . . A mess of ideas. And finally discovered that in fact is not so complicated.

a array is not moving, b constantly backward. So for every 1 a, it is not and will in all positions before his string b 1 contribution answer it.

For example a = 10001 b = 1110011

         10001           10001         10001        10001       10001       10001           10001

      1110011          111001         11100          1110            111             11                   1

For a bit of an array of up to 1, the array will be the highest level of 3 and 1 * 2 ^ 3 contributions answers 4 and b; for a minimum of 1-bit array, the array will contribute to the b phase 1 answer all 5 * 2 ^ 0

Finally, the answer is 53

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+100;
const ll mod =998244353;
int sum[maxn];
char s1[maxn],s2[maxn];

ll powmod(ll a,ll b) {ll res=1;a%=mod; //快速幂 
 for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
 
int main()
{
	int n,m;
	cin>>n>>m>>s1+1>>s2+1;
	for(int i=1;i<=m;i++){//求前缀和 
		if(s2[i]=='1') sum[i]=sum[i-1]+1;
		else sum[i]=sum[i-1];
	}
	
	ll ans=0;
	int t=m-n;//m和n不一样,t的作用是将他们的位置对齐 
	
	for(int i=n;i>=1;i--)//因为后面才是低位,所以从后面往前遍历 
		if(s1[i]=='1'&&i+t>=1)//t位负数时,i+t可能为负数 
		    ans=(ans+powmod(2,(n-i))*sum[i+t])%mod;
	cout<<ans<<endl;
}

 

Guess you like

Origin blog.csdn.net/qq_42129242/article/details/90572670