CF1771
CF1771
Hossam and Combinatorics
建议降红
相当于是最大值个数和最小值个数乘积再乘上
需要注意特判最大值和最小值相等的情况 这时候的答案是
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define pii pair<int,int>
#define fi first
#define se second
#define getchar() cin.get()
#define int long long
const int inf = 0x3f3f3f3f;
const int N = 3e5 + 5;
int read()
{
int f = 1 , x = 0;
char ch = getchar();
while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
return x * f;
}
int n , a[N] , maxx , minn , maxxcnt , minncnt;
signed main ()
{
ios::sync_with_stdio(false);
cin.tie(0) , cout.tie(0);
int T = read();
while ( T -- )
{
n = read();
maxx = maxxcnt = minncnt = 0 , minn = inf;
for ( int i = 1 ; i <= n ; i ++ ) a[i] = read() , maxx = max ( maxx , a[i] ) , minn = min ( minn , a[i] );
for ( int i = 1 ; i <= n ; i ++ )
{
if ( maxx == a[i] ) ++ maxxcnt;
if ( minn == a[i] ) ++ minncnt;
}
cout << ( maxx == minn ? ( n * ( n - 1 ) ) : maxxcnt * minncnt * 2 ) << endl;
}
return 0;
}
Hossam and Friends
我们设
对于一个点对
然后我们从后往前更新
注意
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define pii pair<int,int>
#define fi first
#define se second
#define getchar() cin.get()
#define int long long
const int N = 3e5 + 5;
int read()
{
int f = 1 , x = 0;
char ch = getchar();
while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
return x * f;
}
int n , a[N] , m;
signed main ()
{
ios::sync_with_stdio(false);
cin.tie(0) , cout.tie(0);
int T = read();
while ( T -- )
{
n = read() , m = read();
fill ( a + 1 , a + n + 1 , n );
for ( int i = 1 , x , y ; i <= m ; i ++ ) x = read() , y = read() , a[min(x,y)] = min ( a[min(x,y)] , max(x,y) - 1 );
for ( int i = n - 1 ; i ; i -- ) a[i] = min ( a[i] , a[i+1] );
int ans = 0;
for ( int i = 1 ; i <= n ; i ++ ) ans += ( a[i] - i + 1 );
cout << ans << endl;
}
return 0;
}
Hossam and Trainees
明显比上一场简单...
我们可以先筛出
我们对于一个数 将它质因数分解并记录在
对于
最后我们遍历
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define pii pair<int,int>
#define fi first
#define se second
#define getchar() cin.get()
const int N = 1e5 + 5;
const int maxn = sqrt(1e9);
int read()
{
int f = 1 , x = 0;
char ch = getchar();
while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
return x * f;
}
int n , a[N] , ans , cnt[N];
map<int,int> mp;
int isntprime[N] , prime[N] , tot;
void pre ()
{
for ( int i = 2 ; i <= maxn ; i ++ )
{
if ( !isntprime[i] ) prime[++tot] = i;
for ( int j = 1 ; j <= tot && i * prime[j] <= maxn ; j ++ )
{
isntprime[i*prime[j]] = 1;
if ( ! ( i % prime[j] ) ) break;
}
}
}
signed main ()
{
ios::sync_with_stdio(false);
cin.tie(0) , cout.tie(0);
int T = read();
pre();
while ( T -- )
{
ans = 0 , mp.clear();
memset ( cnt , 0 , sizeof cnt );
n = read();
for ( int i = 1 ; i <= n ; i ++ ) a[i] = read();
for ( int i = 1 ; i <= n ; i ++ )
{
for ( int j = 1 ; j <= tot && a[i] >= prime[j] ; j ++ )
if ( ! ( a[i] % prime[j] ) )
{
++ cnt[j];
while ( ! ( a[i] % prime[j] ) ) a[i] /= prime[j];
}
if ( a[i] > 1 )
{
if ( mp[a[i]] ) { ans = 1; break; }
mp[a[i]] = 1;
}
}
for ( int i = 1 ; i <= tot ; i ++ ) ans |= ( cnt[i] >= 2 );
cout << ( ans ? "YES" : "NO" ) << endl;
}
return 0;
}
Hossam and (sub-)palindromic tree
难度起来了()
先考虑序列上的情况 设
将这个东西转移到树上 即设
最终答案即为
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define pii pair<int,int>
#define fi first
#define se second
#define getchar() cin.get()
const int N = 2e3 + 5;
int read()
{
int f = 1 , x = 0;
char ch = getchar();
while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
return x * f;
}
int n , f[N][N] , fa[N][N] , dep[N][N] , ans;
string s;
vector<int> e[N];
inl void add ( int u , int v ) { e[u].eb(v); }
void clear()
{
for ( int i = 1 ; i <= n ; i ++ ) for ( int j = 1 ; j <= n ; j ++ ) fa[i][j] = dep[i][j] = 0 , f[i][j] = -1;
for ( int i = 1 ; i <= n ; i ++ ) e[i].clear();
ans = 0;
}
void dfs ( int rt , int u , int ff )
{
fa[rt][u] = ff , dep[rt][u] = dep[rt][ff] + 1;
for ( auto v : e[u] ) if ( v ^ ff ) dfs ( rt , v , u );
}
int dp ( int x , int y )
{
if ( f[x][y] != -1 ) return f[x][y];
if ( dep[x][y] == 1 ) return f[x][y] = 1;
if ( dep[x][y] == 2 ) return f[x][y] = ( s[x] == s[y] ) + 1;
return f[x][y] = max ( max ( dp ( fa[y][x] , y ) , dp ( x , fa[x][y] ) ) , dp ( fa[y][x] , fa[x][y] ) + ( ( s[x] == s[y] ) ? 2 : 0 ) );
}
signed main ()
{
ios::sync_with_stdio(false);
cin.tie(0) , cout.tie(0);
int T = read();
while ( T -- )
{
n = read();
clear();
cin >> s; s = " " + s;
for ( int i = 1 , u , v ; i < n ; i ++ ) u = read() , v = read() , add ( u , v ) , add ( v , u );
for ( int i = 1 ; i <= n ; i ++ ) dfs ( i , i , 0 );
for ( int i = 1 ; i <= n ; i ++ ) for ( int j = i ; j <= n ; j ++ ) ans = max ( ans , dp ( i , j ) );
cout << ans << endl;
}
return 0;
}
Hossam and a Letter
类似种花的题
记录
那么我们
注意当
细节很多 状态转移方程不要挂了
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define mid (l+(r-l)/2)
// #define mid ((l+r)/2)
#define ls(p) t[p].son[0]
#define rs(p) t[p].son[1]
#define lson ls(p),l,mid
#define rson rs(p),mid+1,r
#define pii pair<int,int>
#define fi first
#define se second
#define getchar() cin.get()
// #define int long long
const int N = 1e3 + 5;
const int maxn = 2e9;
int read()
{
int f = 1 , x = 0;
char ch = getchar();
while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
return x * f;
}
int n , m , up[N][N][2] , dw[N][N][2] , ans;
char mp[N][N];
signed main ()
{
ios::sync_with_stdio(false);
cin.tie(0) , cout.tie(0);
n = read() , m = read();
for ( int i = 1 ; i <= n ; i ++ )
for ( int j = 1 ; j <= m ; j ++ )
cin >> mp[i][j];
for ( int i = 1 ; i <= n ; i ++ )
for ( int j = 1 ; j <= m ; j ++ )
{
if ( mp[i][j] == '#' ) up[i][j][0] = up[i][j][1] = 0;
else if ( mp[i][j] == '.' ) up[i][j][0] = up[i-1][j][0] + 1 , up[i][j][1] = up[i-1][j][1] + 1;
else up[i][j][0] = 0 , up[i][j][1] = up[i-1][j][0] + 1;
}
for ( int i = n ; i ; i -- )
for ( int j = 1 ; j <= m ; j ++ )
{
if ( mp[i][j] == '#' ) dw[i][j][0] = dw[i][j][1] = 0;
else if ( mp[i][j] == '.' ) dw[i][j][0] = dw[i+1][j][0] + 1 , dw[i][j][1] = dw[i+1][j][1] + 1;
else dw[i][j][0] = 0 , dw[i][j][1] = dw[i+1][j][0] + 1;
}
for ( int i = 1 ; i <= n ; i ++ )
for ( int j = 1 ; j <= m ; j ++ )
if ( mp[i][j] == 'm' ) up[i][j][0] = up[i][j][1] , dw[i][j][0] = dw[i][j][1];
for ( int i = 2 ; i < n ; i ++ )
for ( int j = 1 ; j <= m - 2 ; j ++ )//横杠左端点(i,j)
{
int cnt = ( mp[i][j] == 'm' ) + ( mp[i][j+1] == 'm' );
if ( cnt > 1 || mp[i][j] == '#' || mp[i][j+1] == '#' ) continue;
for ( int k = j + 2 ; k <= m ; k ++ )//横杠右端点(i,k)
{
if ( mp[i][k] == '#' ) break;
cnt += ( mp[i][k] == 'm' );
if ( cnt > 1 ) break;
int res = 0;
if ( up[i][j][0] > 1 && up[i][k][0] > 1 && dw[i][j][0] > 1 && dw[i][k][0] > 1 ) res = max ( res , k - j - 3 + min ( up[i][j][0] , up[i][k][0] ) * 2 + min ( dw[i][j][0] , dw[i][k][0] ) * 2 );
if ( !cnt )
{
if ( up[i][j][1] > 1 && up[i][k][0] > 1 && dw[i][j][0] > 1 && dw[i][k][0] > 1 ) res = max ( res , k - j - 3 + min ( up[i][j][1] , up[i][k][0] ) * 2 + min ( dw[i][j][0] , dw[i][k][0] ) * 2 );
if ( up[i][j][0] > 1 && up[i][k][1] > 1 && dw[i][j][0] > 1 && dw[i][k][0] > 1 ) res = max ( res , k - j - 3 + min ( up[i][j][0] , up[i][k][1] ) * 2 + min ( dw[i][j][0] , dw[i][k][0] ) * 2 );
if ( up[i][j][0] > 1 && up[i][k][0] > 1 && dw[i][j][1] > 1 && dw[i][k][0] > 1 ) res = max ( res , k - j - 3 + min ( up[i][j][0] , up[i][k][0] ) * 2 + min ( dw[i][j][1] , dw[i][k][0] ) * 2 );
if ( up[i][j][0] > 1 && up[i][k][0] > 1 && dw[i][j][0] > 1 && dw[i][k][1] > 1 ) res = max ( res , k - j - 3 + min ( up[i][j][0] , up[i][k][0] ) * 2 + min ( dw[i][j][0] , dw[i][k][1] ) * 2 );
}
ans = max ( ans , res );
}
}
cout << ans << endl;
return 0;
}
Hossam and Range Minimum Query
一个粗略的想法是我们用主席树维护异或前缀和 因为异或的优秀性质 我们可以得知 如果区间内该数的出现次数是偶数 那么整体异或值为
但这样做显然是错的 例如
我们考虑为每一个值赋一个随机哈希值 显然这样出现错误的概率会小很多 用主席树维护即可
注意这里我们如果不开
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define mid (l+(r-l)/2)
// #define mid ((l+r)/2)
#define ls(p) t[p].son[0]
#define rs(p) t[p].son[1]
#define lson ls(p),l,mid
#define rson rs(p),mid+1,r
#define pii pair<int,int>
#define fi first
#define se second
#define getchar() cin.get()
// #define int long long
const int N = 2e5 + 5;
const int maxn = 2e9;
int read()
{
int f = 1 , x = 0;
char ch = getchar();
while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
return x * f;
}
int n , q , a[N] , root[N] , lstans;
string s;
map<int,int> mp;
struct Tree
{
struct node { int son[2] , sum; } t[N<<5];
int tot = 0;
inl int new_node ( int x ) { t[++tot] = t[x]; return tot; }
void upd ( int &p , int l , int r , int x , int val )
{
p = new_node(p) , t[p].sum ^= val;
if ( l == r ) return;
if ( x <= mid ) upd ( lson , x , val );
else upd ( rson , x , val );
}
int query ( int u , int v , int l , int r )
{
if ( l == r ) return l;
if ( t[ls(u)].sum ^ t[ls(v)].sum ) return query ( ls(u) , ls(v) , l , mid );
else return query ( rs(u) , rs(v) , mid + 1 , r );
}
}T;
signed main ()
{
ios::sync_with_stdio(false);
cin.tie(0) , cout.tie(0);
mt19937 rnd(random_device{}());
n = read();
for ( int i = 1 ; i <= n ; i ++ )
{
a[i] = read();
if ( !mp.count(a[i]) ) mp[a[i]] = rnd();
T.upd ( root[i] = root[i-1] , 0 , maxn , a[i] , mp[a[i]] );
}
q = read();
for ( int i = 1 ; i <= q ; i ++ )
{
int l = read() ^ lstans , r = read() ^ lstans;
lstans = T.query ( root[l-1] , root[r] , 0 , maxn );
if ( lstans == maxn ) lstans = 0;
cout << lstans << endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!