2024ICPC成都比赛部分题解
A. Arrow a Row
Define an "arrow string" as a string that meets the following conditions:
- The length of the string is at least \(5\).
- The string starts with > and ends with >>>.
- The rest of the string consists only of -.
For example, >-->>> and >--->>> are valid arrow strings, while >->> and >->->>> are not.
Sauden gives you a string \(s\) of length \(n\), consisting of > and -. You need to create \(s\) by performing a series of painting operations on a string of the same length \(n\) that consists entirely of *. In one painting operation, you can choose a substring of length at least \(5\) and transform it into an arrow string. The total number of operations you perform cannot exceed \(n\).
If it is impossible to obtain the string \(s\) using no more than \(n\) painting operations, output \(\texttt{No}\). Otherwise, output \(\texttt{Yes}\) and provide the details of the painting operations. If there are multiple solutions, output any.
\(Input\)
The first line contains a single integer \(T(1<=T<=10^4)\), indicating the number of test cases.
Each test case contains a string \(s\) of length \(n\)(5<=n<=10^5)in a single line, consisting only of > and -.
It is guaranteed that the sum of \(n\) over all test cases does not exceed\(5*10^5\)
\(Output\)
For each test case, if the given string cannot be obtained by performing no more than \(n\) painting operations, output \(No\) in a single line.
Otherwise, output \(Yes\) and a positive integer \(m\)(1<=m<=n),which denotes the number of painting operations to perform. Then output \(m\) lines,each contains two integers
p(1<=p<=p-4) and &l&(5<=l<=n+1-p), indicating the starting position of the selected substring and its length.
\(Sample\)
4
>>->>>
>>>->
>>>>>
>->>>>>>
————————
Yes 2
1 5
2 5
No
No
Yes 2
2 7
1 5
思路:输出次数给的很宽裕,指针维护,存在还有-时,遇到一个<更新下左指针,并用\(n\)-左指针+1做为长度,输出一次,
没有-时,左指针固定,然后倒序长度每次输出即可,具体可以看看代码
注意:倒序不要越界
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"
using namespace std;
mt19937 rnd(time(0));
const ll mod=1e9+7;
ll ksm(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1)
{
ans=ans%mod*(x%mod)%mod;
}
x=x%mod*(x%mod)%mod;
y>>=1;
}
return ans%mod%mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
vector<pair<ll,ll>>an;
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
//ll n;
an.clear();
string f;
cin>>f;
ll n=f.size();
f='0'+f;
ll pd=0;
ll cnt=0;
for(ll i=1;i<=n;i++)
{
if(f[i]=='-')
{
pd=1;
cnt++;
}
}
ll ans=0;
for(ll i=n;i>=n-2;i--)
{
if(f[i]=='>')ans++;
}
ll l=1;
if(ans==3&&f[1]=='>'&&pd==1)
{
for(ll i=1;i<=n;i++)
{
if(cnt==0)
{
for(ll j=n;j>=i+2;j--)
{
an.push_back({l,j-l+1});
}
break;
}
if(f[i]=='>')
{
l=i;
an.push_back({l,n-l+1});
}
else
{
cnt--;
}
}
cout<<"Yes"<<" "<<an.size()<<endl;
for(auto j:an)
{
cout<<j.first<<" "<<j.second<<endl;
}
}
else
cout<<"No"<<endl;
}
}
B. Athlete Welcome Ceremony
Chengdu is about to host the \(2025\) World Games. During the athlete welcome ceremony at the opening event, there will be \(n\)
volunteers dressed in one of three different types of traditional folk costumes, lined up to welcome the athletes. These costumes are denoted by type
\(a\),\(b\), and \(c\). The positions of the volunteers have been determined, and now we need to assign costumes to the volunteers. To achieve a specific visual effect, adjacent volunteers must not wear the same type of costume.
Among the \(n\) volunteers, some already have one of the three types of folk costumes, while others do not have any and require custom-made costumes provided by the organizers. There are \(Q\) custom-making plans, each specifying: making \(x\) sets of costumes \(a\), \(y\) sets of costumes \(b\) , and \(z\) sets of costumes \(c\).
For each custom-making plan, determine how many different valid costume arrangements can be made after distributing the custom-made costumes to the volunteers who do not have any costumes. Specifically, determine the number of ways for assigning costumes \(a,b and c\) under the condition of not exceeding the limits of the given plan. If two arrangements differ in the type of costume assigned to the same volunteer, they are considered different. Note that the same type of costumes are not distinguished from each other.As the number may be very large, please output the answer modulo \(1e9+7\)
\(Input\)
The first line contains two integers \(n(1<=n<=300)\) ans \(Q(1<=Q<=1e5)\),, representing the number of volunteers and the number of custom-making plans, respectively.
The second line is a string \(s\) of length \(n\). It is guaranteed that the string \(s\) contains only the characters \(a,b,c\) and \(?\). If the i-th character is one of \(a,b\)
and \(c\),, it indicates that the i-th volunteer already has the corresponding costume; otherwise, if it is \(?\), it indicates that the i-th volunteer does not have any costume.
Each of the next \(Q\) lines contains three integers \(x,y,z(0<=x,y,z<=300)\), representing a custom-making plan. It is guaranteed that the sum \(x+y+z\) is no less than the number of volunteers without costumes.
\(Output\)
Output \(Q\)lines, with the i-th line containing an integer that represents the number of valid costume arrangements that satisfy the requirements for the i-th custom-making plan. Please output the answer modulo \(1e9+7\)
\(Smple1\)
6 3
a?b??c
2 2 2
1 1 1
1 0 2
——————
3
1
1
\(Sample2\)
6 3
??????
2 2 2
2 3 3
3 3 3
————————
30
72
96
思路:\(dp[n][m][k]\),取n个a,m个b,k个c的方案数,在遇到?时结算一次,?的滚动数组,
例如:如果在x个?,如果前面不是?,则有\(dp_a[n][m][k]+=dp_a[n-1][m][k]+dp_b[n-1][m][k]+dp_c[n-1][m][k]\)
否则就有\(dp_a[n][m][k]+=dp_b[n-1][m][k]+dp_c[n-1][m][k]\)
所以同理做三个三维dp数组就可了,最后得用三维前缀和优化
注意:赛事开\(long long\)爆了,注意开\(int\)
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll int
#define lowbit(x) (x & -x)
//#define endl "\n"
using namespace std;
const ll mod=1e9+7;
ll dp1[303][303][303];
ll dp2[303][303][303];
ll dp3[303][303][303];
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
ll a1(ll o,ll x,ll y,ll z)
{
ll u=(o%mod+x%mod)%mod;
ll j=(y%mod+z%mod)%mod;
return (u%mod+j%mod)%mod;
}
ll a2(ll x,ll y,ll z)
{
ll u=(x%mod+y%mod)%mod;
ll j=(u%mod+z%mod)%mod;
return j;
}
ll pre[305][305][305];
signed main()
{
fio();
// cout<<1000*mod<<endl;
int n, cp;
string s;
cin >> n >> cp>>s;
s = '*' + s+'*';
int cnt = 1;
int id[405];
for (int i = 1; i <= n; i++) {
if (s[i] == '?') {
id[cnt++] = i;
}
}
cnt--;
//dp[0][0][0][0]
for (int n = 0; n <= cnt; n++) {
for (int m = 0; m <= cnt; m++) {
for (int k = 0; k <= cnt; k++) {
int temp = n + m + k;
if (temp > cnt || temp==0)continue;
if (s[id[temp] - 1] != 'a' && s[id[temp] + 1] != 'a') {
if (dp1[n][m][k] == 0 && n > 0 && temp == 1) {
dp1[n][m][k] = 1;
}
if (n > 0) {
if (s[id[temp] - 1] != '?') {
dp1[n][m][k] =a1(dp1[n][m][k],dp1[n - 1][m][k] , dp2[n - 1][m][k] , dp3[n - 1][m][k])%mod;
}
else {
dp1[n][m][k] = a2(dp1[n][m][k],dp2[n - 1][m][k] , dp3[n - 1][m][k])%mod;
}
}
}
if (s[id[temp] - 1] != 'b' && s[id[temp] + 1] != 'b') {
if (dp2[n][m][k] == 0 && m>0 && temp==1)dp2[n][m][k] = 1;
else {
if (m > 0) {
if (s[id[temp] - 1] != '?') {
dp2[n][m][k]=a1(dp2[n][m][k],dp1[n][m - 1][k] , dp2[n][m - 1][k] , dp3[n][m - 1][k]);
}
else {
dp2[n][m][k] =a2(dp2[n][m][k], dp1[n][m - 1][k] , dp3[n][m - 1][k]);
}
}
}
}
if (s[id[temp] - 1] != 'c' && s[id[temp] + 1] != 'c') {
if (dp3[n][m][k] == 0 && k>0 && temp==1)dp3[n][m][k] = 1;
else {
if (k > 0) {
if (s[id[temp] - 1] != '?') {
dp3[n][m][k] =a1( dp3[n][m][k],dp1[n][m][k - 1] , dp2[n][m][k - 1] , dp3[n][m][k - 1]);
}
else {
dp3[n][m][k] = a2(dp3[n][m][k] ,dp1[n][m][k - 1] , dp2[n][m][k - 1]);
}
}
}
}
}
}
}
ll u=0;
for(int x=0;x<=300;x++)
for(int y=0;y<=300;y++)
for(int z=0;z<=300;z++){
u=0;
if(cnt==x+y+z)
{
u=a1(u,dp1[x][y][z],dp2[x][y][z],dp3[x][y][z])%mod;
}
pre[x][y][z]=(((((((((u%mod+((x-1>=0?pre[x-1][y][z]:0)%mod)%mod)+(y-1>=0?pre[x][y-1][z]:0)%mod)%mod+((z-1>=0?pre[x][y][z-1]:0)%mod)%mod-((x-1>=0&&y-1>=0)?pre[x-1][y-1][z]:0)%mod)%mod)%mod-((x-1>=0&&z-1>=0)?pre[x-1][y][z-1]:0)%mod)%mod-((y-1>=0&&z-1>=0)?pre[x][y-1][z-1]:0)%mod)%mod+((x-1>=0&&y-1>=0&&z-1>=0)?pre[x-1][y-1][z-1]:0))%mod)%mod)%mod;
pre[x][y][z]%=mod;
while(pre[x][y][z]<0)
{
pre[x][y][z]+=mod;
}
}
while(cp--)
{
ll a,b,c;
cin>>a>>b>>c;
cout<<pre[a][b][c]<<endl;
}
}
G. Expanding Array
Given an integer array \(a_1, a_2, \ldots, a_n\) of length \(n\), you can perform any number of operations on this array. In each operation, you can choose two adjacent elements \(a_i\) and \(a_{i+1}\) (\(1 \le i < n\)), and insert one of the following three values between them: \(a_i \ \texttt{and}\ a_{i+1}\), \(a_i \ \texttt{or}\ a_{i+1}\), or \(a_i \oplus a_{i+1}\). Your task is to determine the maximum number of distinct values that can exist in the array after performing any number of operations.
\(Input\)
The first line contains a single integer \(n\) (\(2 \le n \le 10^5\)), representing the length of the array.
The second line contains \(n\) integers \(a_1, a_2, \ldots, a_n\) (\(0 \le a_i \le 10^9\)), representing the elements of the array.
\(Output\)
Output a single integer, representing the maximum number of distinct values that can be obtained in the array after performing any number of operations.
\(Sample1\)
2
2 3
——————
4
\(Sample2\)
2
3 4
——————
4
思路:其实大概原理不太懂,手算枚举了下组合出的新数应该不太多,试着爆枚了下
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"
using namespace std;
mt19937 rnd(time(0));
const ll mod=1e9+7;
ll ksm(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1)
{
ans=ans%mod*(x%mod)%mod;
}
x=x%mod*(x%mod)%mod;
y>>=1;
}
return ans%mod%mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
ll a[250000];
//map<ll,ll>mp;
map<ll,ll>mp,mc;
ll ans=0;
void dfs(ll l,ll r,ll z)
{
if(z==1)
{
if(mc[l^r]==0)
{
mc[l^r]=1;
if(mp[l^r]==0)
ans++,mp[l^r]=1;
dfs((l^r),r,2);
dfs((l^r),l,2);
dfs((l^r),r,3);
dfs((l^r),l,3);
}
return ;
}
else if(z==2)
{
if(mc[l&r]==0)
{
mc[l&r]=1;
if(mp[l&r]==0)
ans++,mp[l&r]=1;
dfs((l&r),r,3);
dfs((l&r),l,3);
dfs((l&r),r,1);
dfs((l&r),l,1);
}
return;
}
else
{
if(mc[l|r]==0)
{
mc[l|r]=1;
if(mp[l|r]==0)
ans++,mp[l|r]=1;
dfs((l|r),r,3);
dfs((l|r),l,3);
dfs((l|r),r,1);
dfs((l|r),l,1);
}
return;
}
}
int main()
{
fio();
ll n;
cin>>n;
for(ll i=1;i<=n;i++)cin>>a[i];
for(ll i=2;i<=n;i++)
{
mc.clear();
if(mp[a[i-1]]==0)ans++;
if(mp[a[i]]==0)ans++;
mp[a[i]]=mp[a[i-1]]=1;
mc[a[i-1]]=1,mc[a[i]]=1;
dfs(a[i-1],a[i],1);
dfs(a[i-1],a[i],2);
dfs(a[i-1],a[i],3);
}
cout<<ans<<endl;
}
附赠一个优化枚举:
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"
using namespace std;
mt19937 rnd(time(0));
const ll mod=1e9+7;
ll ksm(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1)
{
ans=ans%mod*(x%mod)%mod;
}
x=x%mod*(x%mod)%mod;
y>>=1;
}
return ans%mod%mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
set<ll>q;
ll a[250000];
ll ans=0;
int main()
{
fio();
ll n;
cin>>n;
for(ll i=1;i<=n;i++)
{
cin>>a[i];
if(i>=2)
{
q.insert(a[i]);
q.insert(a[i-1]);
q.insert(a[i]&a[i-1]);
q.insert(a[i]|a[i-1]);
q.insert(a[i]^a[i-1]);
q.insert((a[i]&a[i-1])&(a[i]^a[i-1]));
q.insert((a[i-1])&(a[i]^a[i-1]));
q.insert((a[i])&(a[i]^a[i-1]));
}
}
cout<<q.size()<<endl;
}
I. Good Partitions
Lawliet has a sequence of numbers of length \(n\), denoted as \(a_1, a_2, \ldots, a_n\), and he wants to determine how many good partitions exist.
A partition size \(k\) is considered a good partition size if it satisfies \(1 \leq k \leq n\) and, after dividing the sequence \(a\) into parts by partition size, each resulting sub-sequence is non-decreasing. The partitioning method is as follows:
- The sequence \(a\) is divided into \(\lceil \frac{n}{k} \rceil\) parts.
- For the \(i\)-th part (\(1 \leq i \leq \lceil \frac{n}{k} \rceil - 1\)), the elements are \(a_{(i - 1) \times k + 1}, a_{(i - 1) \times k + 2}, \ldots, a_{i \times k}\).
- For the \(\lceil \frac{n}{k} \rceil\)-th part, the elements are \(a_{(\lceil \frac{n}{k} \rceil - 1) \times k + 1}, \ldots, a_n\). Note that the length of the last part may be less than \(k\).
Lawliet finds this problem too simple, so he will make \(q\) modifications. Each modification provides two positive integers \(p\) and \(v\), indicating that the value of \(a_p\) will be changed to \(v\).
Your task is to help Lawliet calculate the number of good partition sizes before any modifications and after each modification.
\(Input\)
The first line contains an integer \(T\) (\(1\le T \le 10\)), representing the number of test cases.
For each test case, the first line contains two integers \(n\) (\(1 \le n \le 2 \cdot 10^5\)) and \(q\) (\(1 \le q \le 2 \cdot 10^5\)), representing the length of the sequence and the number of modifications.
The second line contains \(n\) integers, representing the sequence \(a_1, a_2, \ldots, a_n\) (\(1\le a_i\le 2\cdot 10^9\)).
The following \(q\) lines each contain two integers \(p\) (\(1 \le p \le n\)) and \(v\) (\(1 \le v \le 2 \cdot 10^9\)), indicating that the element at the \(p\)-th position in the sequence will be modified to \(v\).
It is guaranteed that the sum of \(n\) and the sum of \(q\) over all test cases do not exceed \(2\cdot 10^5\), respectively.
\(Output\)
For each test case, output \(q + 1\) lines, representing the number of good partition sizes before any modifications and after each modification.
\(Sample1\)
1
5 2
4 3 2 6 1
2 5
3 5
——————
1
2
3
思路:本题在于区间维护,应该把所有区间长度的\(gcd\)转化为右边界下标的\(gcd\)(除了下标在\(n\))的,然后发现除了\(1~n\)为一个区间的情况答案为\(n\),其他情况
答案均为所有区间右边界下标\(gcd\)出来的数的因数(除了右边界为\(n\)),于是欧拉筛(最好用数组记一个数的因子个数)+线段树维护区间\(gcd\)就可以做出来了,
然后每次修改只会影响修改位置的数和它前面的数,每次看看有没有形成新区间再看是否添加下标,非区间边界的数赋值为\(0\),
总时间复杂度为\(n*logn*logn\),开个\(int\)能过,开\(long long\)易\(TLE\)
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"
using namespace std;
const ll maxn = 2e5+5;
ll gcd(ll x,ll y)
{
if(y==0)
return x;
else return gcd(y,x%y);
}
struct s
{
ll l, r;
ll ad, v, cf;//ad为加法的懒惰标记,cf为乘法的懒惰标记
}p[maxn << 2];
void build(ll i, ll l, ll r)
{
p[i].l = l,p[i].r = r,p[i].v = 0;
p[i].ad = 0;
if(l==r)
{
return ;
}
build(i << 1, l, (l + r) >> 1);
build(i << 1 | 1, ((l + r) >> 1) + 1, r);
}
void udq(ll i, ll ad, ll cf, ll l, ll r)//区间修改
{
if (p[i].l == l && p[i].r == r)
{
p[i].v=ad;
return;
}
ll i1 = i << 1, i2 = i << 1 | 1;
if (l <= p[i1].r)
{
if (r <= p[i1].r)
udq(i1, ad, cf, l, r);
else
udq(i1, ad, cf, l, p[i1].r);
}
if (r >= p[i2].l)
{
if (l >= p[i2].l)
{
udq(i2, ad, cf, l, r);
}
else
udq(i2, ad, cf, p[i2].l, r);
}
p[i].v =gcd(p[i1].v,p[i2].v);
}
ll query(ll i, ll l, ll r)
{
ll ans = 0;
if (p[i].l == l && p[i].r == r)
{
ans = gcd(ans,p[i].v);
return ans;
}
ll i1 = i << 1, i2 = i << 1 | 1;
if (l <= p[i1].r)
{
if (r <= p[i1].r)
ans = gcd(ans ,query(i1, l, r));
else
ans = gcd(ans , query(i1, l, p[i1].r));
}
if (r >= p[i2].l)
{
if (l >= p[i2].l)
{
ans = gcd(ans , query(i2, l, r));
}
else
ans = gcd(ans,query(i2, p[i2].l, r));
}
return ans;
}
inline ll read()
{
ll 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*10+ch-'0',ch=getchar();
return x*f;
}
ll a[250000];
ll mp[250000];
int main()
{
for(ll i=1;i<=200000;i++)
{
for(ll j=1;j*j<=i;j++)
{
if(j*j==i)
{
mp[i]++;
continue;
}
if(i%j==0)
{
mp[i]+=2;
}
}
}
ll t;
t=read();
while(t--)
{
ll n,m;
n=read();
m=read();
build(1,1,n);
ll u=(ll)0;
for(ll i=1;i<=n;i++)
{
a[i]=read();
if(u<=a[i])
{
u=a[i];continue;
}
else
{
u=a[i];
udq(1,i-1,0,i-1,i-1);
}
}
ll k=query(1,1,n);
if(k==0)
{
cout<<n<<endl;
}
else
{
cout<<mp[k]<<endl;
}
while(m--)
{
ll wz,z;
wz=read();
z=read();
if(n==1)
{
cout<<1<<endl;
continue;
}
if(wz==1)
{
a[wz]=z;
if(a[wz]<=a[wz+1])
{
udq(1,0,0,wz,wz);
}
else
{
udq(1,wz,0,wz,wz);
}
ll k=query(1,1,n);
if(k==0)
{
cout<<n<<endl;
}
else
{
cout<<mp[k]<<endl;
}
}
else if(wz==n)
{
a[wz]=z;
//cout<<z<<endl;
udq(1,0,0,wz,wz);
//cout<<a[wz]<<endl;
if(a[wz-1]<=a[wz])udq(1,0,0,wz-1,wz-1);
else udq(1,wz-1,0,wz-1,wz-1);
ll k=query(1,1,n);
//cout<<k<<endl;
if(k==0)
{
cout<<n<<endl;
}
else
{
cout<<mp[k]<<endl;
}
continue;
}
else
{
a[wz]=z;
if(a[wz-1]>a[wz])
{
udq(1,wz-1,0,wz-1,wz-1);
}
else
{
udq(1,0,0,wz-1,wz-1);
}
if(a[wz]>a[wz+1])
{
udq(1,wz,0,wz,wz);
}
else
udq(1,0,0,wz,wz);
ll k=query(1,1,n);
if(k==0)
{
cout<<n<<endl;
}
else
{
cout<<mp[k]<<endl;
}
}
}
}
}
J. Grand Prix of Ballance
Ballance is a classic game where players use the keyboard to control a ball through complex structures high above the ground, avoiding falls while solving puzzles to reach the end of each level. Recently, the player community has developed online mods and hosts regular online competitions, such as the Grand Prix of Ballance.
The Grand Prix consists of \(n\) levels, numbered from \(1\) to \(n\), with \(m\) participants, numbered from \(1\) to \(m\). The competition uses a point system: players earn points based on their ranking in each level, and the sum of their points across all levels determines the final standings. Each level has a designated start time, and participants must complete the level as quickly as possible. As a staff member, you receive a server log during the match containing three types of messages (it is guaranteed that \(1\le x\le n\) and \(1\le id\le m\)):
- 1 x — Type 1: the match on Level \(x\) has started.
- 2 id x — Type 2: participant indexed \(id\) has completed Level \(x\).
- 3 id x — Type 3: participant indexed \(id\) voluntarily gives up completing Level \(x\).
A Type 1 message indicates the start of Level \(x\) until a new Type 1 message appears for a different level. Only messages that correspond to the currently active level are considered valid; all messages for other levels should be ignored. Messages before the first Type 1 message are also ignored. Each level appears at most once in a Type 1 message.
Each player may yield multiple Type 2 and Type 3 messages per level, but only the first valid message counts. Specifically: - Messages are ignored if they do not match the active level indicated by the Type 1 message.
- If a player's first valid message for a level is Type 2, they are considered to have completed the level successfully at that moment, and the player's any subsequent messages for that level are ignored.
- If a player's first valid message for a level is Type 3, they are considered to have given up completing the level at that moment, and the player's any subsequent messages for that level are ignored.
- If a player yields no messages for a level, they are considered not to have completed the level.
Points are awarded to participants who complete the level as follows: the first player to complete the level receives \(m\) points, the second receives \(m-1\) points, and so on. Participants who do not complete the level, including those who give up, receive no points.
Your task is to output the current total points of each participant in descending order based on the log. If multiple participants have the same points, they should be listed in ascending order by their index.
\(Input\)
The first line contains an integer \(T\) (\(1 \leq T \leq 10^4\)), indicating the number of test cases.
For each test case, the first line contains three integers \(n\), \(m\), and \(q\) (\(1 \leq n \leq 10^5\), \(2 \leq m \leq 10^5\), \(1 \leq q \leq 2 \cdot 10^5\)), indicating the number of levels, participants, and log messages, respectively.
The following \(q\) lines contain the log messages as specified above. Of course, the messages are presented in chronological order. The log may not contain all levels, as you may receive it midway through the competition. You only need to process the current results.
It is guaranteed that the sum of \(n\), the sum of \(m\), and the sum of \(q\) over all test cases do not exceed \(5 \cdot 10^5\), respectively.
\(Output\)
For each test case, output \(m\) lines, each containing two integers: \(id\) and \(x\), where \(id\) is the participant's index and \(x\) is their total points, sorted in descending order of points. If multiple participants have the same points, list them in ascending order by their index.
思路:说了很多东西,其实问题不复杂,如果读入1,则表示一个比赛的开始,读入2表示某个编号的人在某场比赛是否赢了(注意去重复和看看是否比赛开始还得看看有没放弃),读入3表示某人放弃了某场比赛(每次新比赛开始,之前的全作废,这个也得看看放弃的比赛是否现在进行的)
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"
using namespace std;
mt19937 rnd(time(0));
const ll mod=1e9+7;
ll ksm(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1)
{
ans=ans%mod*(x%mod)%mod;
}
x=x%mod*(x%mod)%mod;
y>>=1;
}
return ans%mod%mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
vector<pair<ll,ll>>an;
bool vis[250000];
struct s
{
ll v;ll id;
}p[250000];
bool cmp(s x,s y)
{
if(x.v!=y.v)
return x.v>y.v;
else return x.id<y.id;
}
map<ll,ll>mp;
map<pair<ll,ll>,ll>mc;
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
ll n,m,q;
cin>>n>>m>>q;
for(ll i=1;i<=n;i++)vis[i]=0;
for(ll i=1;i<=m;i++)p[i].id=i,p[i].v=0;
ll l=0;
ll cnt=0;
while(q--)
{
ll op;
cin>>op;
if(op==1)
{
ll u;
cin>>u;
vis[l]=0,vis[u]=1;
l=u;
cnt=m;
mp.clear();
mc.clear();
}
else if(op==2)
{
ll id,x;
cin>>id>>x;
if(vis[x]&&mp[id]==0&&mc[{id,x}]==0)
{
p[id].v+=cnt;
cnt--;
mp[id]=1;
}
}
else
{
ll id,x;
cin>>id>>x;
mc[{id,x}]=1;
}
}
sort(p+1,p+1+m,cmp);
for(ll i=1;i<=m;i++)
{
cout<<p[i].id<<" "<<p[i].v<<endl;
}
}
}
L. Recover Statistics
You recently conducted a survey on how much time university students spend commuting from their dorms to school buildings. You believe that this survey could significantly improve campus planning, making commuting easier for both students and faculty. As part of your analysis, you calculated the P50, P95, and P99 commute times to support your conclusions. Here, P\(x\) commute time being \(y\) means that exactly \(x\%\) of the commute times in the entire dataset are less than or equal to \(y\). For example, the P50 of the set \(\{1, 1, 4, 5, 1, 4\}\) can be \(1\), \(2\) or \(3\), since there are exactly \(6 \times 50\% = 3\) values less than or equal to \(1\), \(2\) or \(3\). However, there are no valid P95 or P99 for these values because \(6 \times 95\%\) and \(6 \times 99\%\) are not integers.
Unfortunately, something went wrong — you accidentally deleted the entire dataset. The only values you have left are the P50, P95, and P99 of the commute times. Since you do not have time to redo the survey, you need to reconstruct a set of data that matches all of the P50, P95, and P99 values.
\(Input\)
The input consists of three lines. The first line contains a single integer \(a\), representing the P50 value. The second line contains a single integer \(b\), representing the P95 value. The third line contains a single integer \(c\), representing the P99 value. (\(1 \le a < b < c < 10^9\))
\(Output\)
Output two lines. The first line should contain a single integer \(n\) (\(100 \le n \le 10^5\)), representing the length of the data set.
The second line should contain \(n\) integers \(a_1, a_2, \ldots, a_n\) (\(1 \le a_i \le 10^9\)), representing the reconstructed data set. The integers can be in any order. Any output that meets the requirements will be considered correct.
\(Sample\)
50
95
99
——————
100
1 2 ... 100
思路:构造一个数组保证\(a\)小于等于\(50%\)分位数,\(b\)小于等于\(95%\)分位数,\(c\)小于等于\(99%\)分位数
所以前50个数为a,后45个数为b,再来4个数为c,最后一个数等于\(10^9\)
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"
using namespace std;
mt19937 rnd(time(0));
const ll mod=1e9+7;
ll ksm(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1)
{
ans=ans%mod*(x%mod)%mod;
}
x=x%mod*(x%mod)%mod;
y>>=1;
}
return ans%mod%mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
//map<ll,ll>mp;
int main()
{
fio();
ll n,m,k;
cin>>n>>m>>k;
cout<<100<<endl;
for(ll i=1;i<=50;i++)cout<<n<<" ";
for(ll i=1;i<=45;i++)cout<<m<<" ";
for(ll i=1;i<=4;i++)cout<<k<<" ";
cout<<(ll)1e9<<endl;
}