11.1多校聯訓
阿新 • • 發佈:2021-11-01
T1 並王(bing)
Sol
卡常臭題。但是關我一個考場寫\(O(n^3)\)暴力什麼事呢?
好像可以優化到\(\sum_{i=1}^n f(n)\),\(f(n)\)表示\(n\)二進位制下1
的個數。但是這是基於隨機資料優化。如果全部是\(2^{64}-1\)那效率甚至不如我的。
按位統計。從左往右:
如果第\(i\)個數二進位制第\(j\)位是1
,那麼這一位貢獻就是\(\frac{(i-1)*(i-2)}{2}*(1<<j)\),表示前面隨便選兩個數都可以;同時\(t_j++\),表示目前有多少數第\(j\)位是1
。
如果第\(i\)個數二進位制第\(j\)位是0
,那麼這一位貢獻就是\(f_j*(i-1-f_j)*(1<<j)\)
1
,一個是0
的,這樣異或起來就是1
。綜上所述:開一個桶統計每一位當前
1
個數,時間複雜度\(O(64*n)\),且常數非常小(當然大於\(1\))。只帶O2只能1.09秒,火車頭加上輕鬆過。Code
#include<bits/stdc++.h> #define int unsigned long long using namespace std; const int N=4000005; int n, k; int a[N], ans, U, seed; int t[64]; signed main() { freopen("bing.in", "r", stdin); freopen("bing.out", "w", stdout); scanf("%llu%llu%llu", &n, &seed, &k); U=(k==64?0ull:(1ull<<k))-1ull; mt19937_64 rnd(seed); for(int i=1; i<=n; ++i) { a[i]=rnd()&U; //do sth for(int j=63;~j;j--) { if((a[i]&(1ull<<j))) { ans+=(i-1ull)*(i-2ull)/2ull*(1ull<<j); t[j]++; }else ans+=t[j]*(i-1ull-t[j])*(1ull<<j); } } printf("%llu\n", ans); return 0; }
T2、T3
都不會。不過T3的80分可以提一下。
對於80分,假設一共有\(k\)個島嶼\(x\)塊陸地,先\(O(n^2)\)DFS一遍算出每個點屬於的島嶼。然後\(O(x^2)\)計算一對島嶼之間的直飛距離。由於直飛距離顯然\(\leq n+m\),所以設\(dp[i][j]\)表示已經過長度為\(i\),現在在\(j\)最多坐了幾次飛機。那麼列舉每條邊即可,時間複雜度\(O(k^2n)\),雖然在最壞條件下\(subtask\ 3\;n\leq 90\)是過不了的,但是實際上資料比較水且本題1.5s開O2,所以能喜提80分。
T4 瑪雅歷(maya)
和julian異曲同工的臭題。
最大的統計天數也不超過long long資料範圍,所以先把輸入轉換成總計天數。然後把這個天數分段處理,我的做法分的比較細,先8月,然後-3114年,然後-3113-3101年,然後-3101
每次都更新一下當前時間,注意細節即可。票池的解法是先把400年的大迴圈暴力預處理出來,這裡時間複雜度\(O(10^5)\),很低。然後直接不斷取模再尋找對應日期就可以了,注意跨年的特殊處理即可。很可惜,最後突然改題幹以後票池炸了,或許慢慢來分類更穩吧。
Code(臭死了)
#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace io
{
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=0;c=getchar();}
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c&15),c=getchar();
return f?x:-x;
}
inline void print(int x)
{
static int s[20],len;
len=0;bool flag=0;
if(x<0)flag=1,x=-x;
if(x==0)
{
putchar('0');return;
}
while(x)
{
s[++len]=x%10;
x/=10;
}
for(int i=len;i;i--)putchar(s[i]+'0');
if(flag)putchar(' '),putchar('B'),putchar('C');
return;
}
}
int T,day;
const int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
const int moth[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int nd,nm,ny;
inline void output()
{
using namespace io;
print(day+1);putchar(' ');print(nm);putchar(' ');print(ny);putchar('\n');return;
}
inline void sibai()
{
if(day<=36524)
{
ny+=4*(day/1461);
day%=1461;
if(day>=366)
{
day-=366;ny++;
ny+=(day/365);
day%=365;
while(day>=month[nm])
{
day-=month[nm];nm++;
}
output();return;
}else
{
while(day>=moth[nm])
{
day-=moth[nm];nm++;
}
output();return;
}
}
day-=36525;ny+=100;
ny+=100*(day/36524);
day%=36524;
if(day<=1459)
{
ny+=(day/365);
day%=365;
while(day>=month[nm])
{
day-=month[nm];nm++;
}
output();return;
}
day-=1460;ny+=4;
ny+=4*(day/1461);
day%=1461;
if(day>=366)
{
day-=366;ny++;
ny+=(day/365);
day%=365;
while(day>=month[nm])
{
day-=month[nm];nm++;
}
output();return;
}else
{
while(day>=moth[nm])
{
day-=moth[nm];nm++;
}
output();return;
}
}
signed main()
{
freopen("maya.in","r",stdin);
freopen("maya.out","w",stdout);
using namespace io;
T=read();
while(T--)
{
day=0;nd=11,nm=8,ny=-3114;
for(int i=1;i<=9;i++)day=day*(i==8?18:20)+read();
// cout<<day<<endl;
if(day<=20)
{
nd+=day;print(nd);putchar(' ');print(nm);putchar(' ');print(ny);putchar('\n');continue;
}
day-=21;nm=9;
if(day<=121)
{
while(day>=month[nm])
{
day-=month[nm],nm++;
}
output();continue;
}
day-=122;nd=1;nm=1;ny=-3113;
if(day<=4382)
{
ny+=4*(day/1461);
day%=1461;
if(day>=366)
{
day-=366;ny++;
ny+=(day/365);
day%=365;
while(day>=month[nm])
{
day-=month[nm];nm++;
}
output();continue;
}else
{
while(day>=moth[nm])
{
day-=moth[nm];nm++;
}
output();continue;
}
}
day-=4383;nm=1;ny=-3101;
if(day<=109571)
{
ny+=100*(day/36524);
day%=36524;
if(day<=1459)
{
ny+=(day/365);
day%=365;
while(day>=month[nm])
{
day-=month[nm];nm++;
}
output();continue;
}
day-=1460;ny+=4;
ny+=4*(day/1461);
day%=1461;
if(day>=366)
{
day-=366;ny++;
ny+=(day/365);
day%=365;
while(day>=month[nm])
{
day-=month[nm];nm++;
}
output();continue;
}else
{
while(day>=moth[nm])
{
day-=moth[nm];nm++;
}
output();continue;
}
}
day-=109572;nm=1;ny=-2801;
if(day<=1022678)
{
ny+=400*(day/146097);
day%=146097;
sibai();continue;
}
day-=1022679;
if(day<=366)
{
nm=1;ny=-1;
while(day>=moth[nm])
{
day-=moth[nm];nm++;
}
output();continue;
}
nm=1;ny=0;
ny+=400*(day/146097);
day%=146097;
sibai();
}
return 0;
}