8.18 模拟赛
预计得分:\(0+100+60+?\)
实际得分:\(0+100+60+15\)
T2
洛谷\(P2899\) 人口普查题
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define int long long
const int N = 1e6 + 5;
const int inf = 0x3f3f3f3f3f3f3f3f;
char buf[1<<24] , *p1 , *p2;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<24,stdin),p1==p2)?EOF:*p1++)
//#define getchar() cin.get();
int read()
{
int x = 0 , f = 1;
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 , f[N][3] , a[N];
vector<int> e[N];
inl void add ( int u , int v ) { e[u].eb(v); }
void dfs ( int u , int fa )
{
f[u][1] = a[u] , f[u][0] = 0 , f[u][2] = 0;
if ( e[u].size() == 1 ) f[u][2] = inf;
int flag = 0 , minn = inf;
for ( auto v : e[u] )
if ( v ^ fa )
{
dfs ( v , u );
f[u][0] += min ( f[v][1] , f[v][2] );
f[u][1] += min ( f[v][0] , min ( f[v][1] , f[v][2] ) );
if ( f[v][1] <= f[v][2] ) flag = 1 , f[u][2] += f[v][1];
else f[u][2] += f[v][2] , minn = min ( minn , f[v][1] - f[v][2] );
}
if ( !flag && minn != inf ) f[u][2] += minn;
}
signed main ()
{
freopen ( "router.in" , "r" , stdin );
freopen ( "router.out" , "w" , stdout );
ios::sync_with_stdio(false);
cin.tie(nullptr) , cout.tie(nullptr);
n = read();
for ( int i = 1 ; i <= n ; i ++ ) a[i] = read();
for ( int i = 1 , u , v ; i < n ; i ++ ) u = read() , v = read() , add ( u , v ) , add ( v , u );
add ( 0 , 1 ) , add ( 1 , 0 );
dfs ( 1 , 0 );
cout << min ( f[1][1] , f[1][2] ) << endl;
return 0;
}
T3
\(2h\)思考怒砍\(15pts\)
最后发现\(70pts\)是一个在赛时想过的思路 但是没有深入去想这个性质就被否决了 即为"更相减损术"
发现一个性质:如果\(x,y\)是固定的 那么它从哪儿推过来也是确定的(分\(x>y\)和\(x\le y\)两种情况)
那么我们在搜索树上向前跳 如果跳过头了就回到刚好大于等于查询的点的位置 再递归解决跳到的节点即可
\(70pts\)代码:
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define int long long
const int N = 5e4 + 5;
char buf[1<<24] , *p1 , *p2;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<24,stdin),p1==p2)?EOF:*p1++)
// #define getchar() cin.get();
int read()
{
int x = 0 , f = 1;
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 , c , d;
struct node { int x , y; } a[N];
int solve ( int x , int y )
{
if ( x == c && y == d ) return 1;
if ( x < c || y < d ) return 0;
if ( x > y )
{
int lstx = x; x %= y;
if ( x < c ) x += ( c - x + y - 1 ) / y * y;
if ( x == lstx ) return 0;
return solve ( x , y );
}
else
{
int lsty = y; y %= x;
if ( y < d ) y += ( d - y + x - 1 ) / x * x;
if ( y == lsty ) return 0;
return solve ( x , y );
}
}
signed main ()
{
freopen ( "up.in" , "r" , stdin );
freopen ( "up.out" , "w" , stdout );
ios::sync_with_stdio(false);
cin.tie(nullptr) , cout.tie(nullptr);
n = read() , q = read();
for ( int i = 1 ; i <= n ; i ++ ) a[i].x = read() , a[i].y = read();
for ( int i = 1 ; i <= q ; i ++ )
{
c = read() , d = read();
int ans = 0;
for ( int j = 1 ; j <= n ; j ++ )
if ( c <= a[j].x && d <= a[j].y && solve ( a[j].x , a[j].y ) ) ans ++;
cout << ans << endl;
}
return 0;
}
T4
\(60pts\)显然 卡卡常能\(100pts\)
\(60pts\)代码:
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
const int N = 5e4 + 5;
char buf[1<<24] , *p1 , *p2;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<24,stdin),p1==p2)?EOF:*p1++)
//#define getchar() cin.get();
int read()
{
int x = 0 , f = 1;
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 , f[N];
struct node { int pos[6]; friend bool operator < ( const node &x , const node &y ) { for ( int i = 1 ; i <= 5 ; i ++ ) if ( x.pos[i] > y.pos[i] ) return 0; return 1; } } a[N];
signed main ()
{
freopen ( "frog.in" , "r" , stdin );
freopen ( "frog.out" , "w" , stdout );
ios::sync_with_stdio(false);
cin.tie(nullptr) , cout.tie(nullptr);
n = read();
for ( int i = 1 ; i <= n ; i ++ ) { for ( int j = 1 ; j <= 5 ; j ++ ) a[i].pos[j] = read(); f[i] = read(); }
for ( int i = 1 ; i <= n ; i ++ )
{
int maxx = 0;
for ( int j = 1 ; j < i ; j ++ )
if ( a[j] < a[i] ) maxx = max ( maxx , f[j] );
f[i] += maxx;
}
for ( int i = 1 ; i <= n ; i ++ ) cout << f[i] << endl;
return 0;
}