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;
}